Logging is a fundamental aspect of software development, serving as a critical tool for diagnosing issues, understanding application behavior, and ensuring the reliability of your code. However, finding the right logging solution that is both versatile and high-performing can be a daunting task. Enter JLogger6, a .NET 6 library component designed to redefine the way you handle logging in your .NET projects.
In this comprehensive guide, we’ll explore the powerful capabilities of JLogger6 and how it can simplify your logging efforts while enhancing your application’s performance. Whether you’re a seasoned developer or just starting your journey, JLogger6 offers a wealth of features to meet your logging needs efficiently and effectively.
Introducing JLogger6: A Versatile Singleton Component
JLogger6 is a singleton component, making it accessible from any part of your .NET application. It seamlessly integrates with any .NET project that supports .NET 6, offering a wide array of features tailored to meet the demands of modern software development. Here’s a quick overview of what JLogger6 brings to the table:
1. Multithreaded Use
As a singleton, JLogger6 is accessible from any thread within your application. It employs advanced locking techniques to ensure that log entries from multiple threads don’t collide, guaranteeing the integrity of your logs.
2. High Throughput Logging
JLogger6 is designed to handle high-throughput scenarios with ease. Even when multiple threads are concurrently writing log entries, it won’t hinder the performance of your application. Instead, it utilizes a first-in, first-out (FIFO) queue mechanism, where log writes are enqueued and processed in the background by a separate thread, ensuring minimal impact on your application’s responsiveness.
3. Email Integration
For added convenience, JLogger6 allows you to configure log entries to trigger email notifications. This feature can be invaluable for keeping your development and operations teams informed about critical events in your application. To enable this, you’ll need to provide the necessary SMTP configuration data.
4. Multiple Log Entry Types
JLogger6 offers several log entry types to choose from. These log types can be customized to suit your specific needs, giving you the flexibility to categorize and manage log entries as desired. Some log types are reserved for the component’s internal use and are automatically ignored during log processing.
5. Daily Log Files
JLogger6 automatically generates new log files daily, ensuring that your logs are organized by date and time. This feature simplifies the process of identifying when specific events occurred within your application.
6. Log Retention
To prevent log files from accumulating indefinitely, JLogger6 includes an automatic log retention feature. You can specify the number of days to retain log files, or set it to zero to preserve all log files. This functionality keeps your storage space tidy and efficient.
7. Tab-Delimited Log Files
All log entries created by JLogger6 are stored in tab-delimited files. This format facilitates easy analysis and manipulation of log data using spreadsheet software like Excel.
8. Optional Database Logging
For those who prefer database storage over file-based logs, JLogger6 provides the option to log directly to an SQL Server database. Included SQL scripts make it easy to set up the necessary database objects, such as the DBLog table and associated stored procedures for inserting log records and performing log retention.
9. Azure File Storage Integration
JLogger6 also offers seamless integration with Azure File Storage. When your log is closed, the log file is automatically copied to Azure File Storage and removed locally. This ensures that your logs are securely stored in the cloud, making them accessible from anywhere.
Getting Started with JLogger6
Setting up the Logger
Configuring JLogger6 is straightforward. One of its key features is the LOG_TYPE Enumeration, which allows you to specify the type of log entry and determine whether it should be recorded or not. This dynamic setup enables you to adjust your logging preferences at runtime, providing greater flexibility.
Here’s a step-by-step guide to configuring the Logger:
- Define your desired log options using the LOG_TYPE enumeration. These options can vary between development, QA, production, and troubleshooting scenarios.
LOG_TYPE m_DebugLogOptions = LOG_TYPE.Error | LOG_TYPE.Informational | LOG_TYPE.ShowTimeOnly | LOG_TYPE.Warning | LOG_TYPE.HideThreadID | LOG_TYPE.ShowModuleMethodAndLineNumber | LOG_TYPE.System | LOG_TYPE.SendEmail;
- Set up variables to configure the Logger. This is typically done in your application’s startup code.
Boolean response = false;
String filePath = CommonHelpers.CurDir + @"\";
String fileNamePrefix = "MyLog";
Int32 daysToRetainLogs = 30;
response = Logger.Instance.SetLogData(filePath, fileNamePrefix, daysToRetainLogs, logOptions, "");
- If you prefer database logging, use the following code as an example to configure JLogger6 for SQL Server. Make sure to execute the provided SQL scripts on your target SQL Server to create the required database objects.
Boolean response = false;
String serverInstanceName = "MyComputer.SQL2020";
String dbUserName = "";
String dbPassword = "";
Boolean useWindowsAuthentication = true;
Boolean useDBLogging = true;
String databaseName = "myData";
response = Logger.Instance.SetDBConfiguration(serverInstanceName, dbUserName, dbPassword, useWindowsAuthentication, useDBLogging, databaseName);
- If you’d like to store log files in Azure File Storage, configure JLogger6 as follows:
String resourceID = "<AZURE_CONNECTION_STRING>";
String fileShareName = "<AZURE_FILE_SHARE_NAME>";
String directoryName = "<AZURE_DIRECTORY_NAME>";
response = Logger.Instance.SetAzureConfiguration(resourceID, fileShareName, directoryName, true);
- To enable email notifications for specific log entries, configure the email settings:
Int32 smtpPort = 587;
Boolean useSSL = true;
Once your Logger is configured, it’s ready to capture log entries based on your specified settings.
Logging Example in Code
JLogger6 provides a straightforward approach to log entries, allowing you to focus on the essential aspects of your application. Here’s an example of how to log entries in your code:
if ((m_DebugLogOptions & LOG_TYPE.Error) == LOG_TYPE.Error)
Logger.Instance.WriteDebugLog(LOG_TYPE.Error & LOG_TYPE.SendEmail, exUnhandled, "Optional Specific message if desired");
This code checks if the Error log type is enabled in your settings before writing an error log entry. You can customize log messages and specify additional information as needed.
JLogger6 is designed with performance in mind. The use of bitset comparisons before invoking logging methods ensures that unnecessary logging code is not executed, minimizing any performance impact. This design allows for the inclusion of extensive logging in your codebase without affecting performance unless explicitly needed.
For developers using the ILogger interface in .NET applications, JLogger6 seamlessly integrates. You can obtain a reference to the ILogger interface from the Logger.Instance object, allowing you to leverage JLogger6 within your existing application structure.
Here’s a quick overview of how LogLevel translations map to JLogger6 log types:
- LogLevel.Critical adds LOG_TYPE.Fatal to the debug log options.
- LogLevel.Debug adds LOG_TYPE.System to the debug log options.
- LogLevel.Error adds LOG_TYPE.Error to the debug log options.
- LogLevel.Information adds LOG_TYPE.Informational to the debug log options.
- LogLevel.Warning adds LOG_TYPE.Warning to the debug log options.
- LogLevel.Trace adds LOG_TYPE.Flow to the debug log options.
These mappings ensure that your existing logging code can smoothly transition to JLogger6 without major modifications.
A Closer Look at the Log
The log generated by JLogger6 offers a wealth of information to aid in diagnostics and analysis. When the log begins, JLogger6 captures various system values that prove invaluable during troubleshooting. The log columns include:
- Time (or Date/Time): Displays the timestamp, down to the millisecond, depending on the LOG_TYPE flag configuration.
- Log Type: Indicates the log entry’s type, corresponding to the LOG_TYPE value used.
- Message: Contains the primary message associated with the log entry.
- Additional Info: Provides supplementary details to enhance the understanding of the message.
- Exception Data: Displays name-value pairs from an exception’s Data collection, a crucial resource for efficient troubleshooting.
- Stack Info: Offers stack information extracted from the exception instance.
- Module: Specifies the module where the log entry originated.
- Method: Identifies the method responsible for the log entry.
- Line No.: Indicates the line number within the source code where the log entry was triggered.
- Thread ID: Displays the .NET thread ID if provided.
This well-structured log format simplifies the process of pinpointing issues and analyzing application behavior. You can even open the log file directly in Excel for more advanced searching and analysis capabilities.
The Demo App: A Practical Example
To help you understand how to use JLogger6 effectively, a demo application has been created. This .NET 6 Windows Forms application provides hands-on experience with various configurations and scenarios, showcasing how JLogger6 can be utilized in real-world situations.
- Log File Configuration: Explore how JLogger6 operates with traditional log files.
- Azure File Storage Configuration: Witness the seamless integration with Azure File Storage for cloud-based log storage.
- Database Configuration: Learn how to set up JLogger6 for direct database logging with SQL Server.
- Code Exploration: Dive into the codebase to see practical examples of JLogger6 usage.
The demo application’s full source code is available on GitHub, allowing you to step through it and experiment with different configurations to better understand how JLogger6 can benefit your projects.
What’s on the Horizon
The development of JLogger6 doesn’t stop here. Future updates will bring even more features and enhancements to further empower developers in their logging efforts. Here are some exciting developments to look forward to:
JLogger6 is evolving to support user-defined fields in both file-based logs and databases. This feature will enable developers to define and create custom fields when configuring the logger. These fields can evolve over time, adapting to the unique requirements of different applications.
Database Log Audit
A new option for database log storage is in the works. It will introduce an audit table to track records deleted from the DBLog table. This functionality is particularly valuable for those who need to maintain a detailed record of log actions and deletions.
JLogger6 is the result of over 40 years of software development experience, aimed at simplifying and enhancing the logging experience for developers. It addresses the need for versatile, high-performance logging without compromising your application’s execution speed.
While developers may have their favorite logging tools, JLogger6 offers a compelling alternative. Its dynamic configuration, efficient bitset comparisons, and high-throughput design make it a valuable asset in any developer’s toolkit. Whether you’re building a small application or a complex enterprise system, JLogger6 adapts to your needs, ensuring that logging remains a powerful tool in your arsenal.