ThingWorx Edge .NET SDK Reference > Using Logging with the ThingWorx Edge .NET SDK
Using Logging with the ThingWorx Edge .NET SDK
As of release 5.8.0 of the ThingWorx Edge .NET SDK, the SDK provides the full Apache log4net distribution, v.2.0.8. One advantage of log4net is its hierarchical architecture, which makes it possible to enable logging at runtime on individual components, without modifying the application binary. Instead of changing code, you use XML configuration files. Log statements can remain in shipped code without incurring a high performance cost. Further, you can write your logs to different places by simply changing your configuration. For example, you can write your .NET logs to a file, a database, or a log management system.For complete information about the features of Apache log4net and the frameworks that it supports, refer to the topic, "Apache log4net Features," in the <dotnet-sdk-v.v.v>/dependencies/log4net-2.0.8/doc/release/ subdirectory of the Apache distribution (features.html) that is provided with the .NET SDK.
In addition, you will find the following changes to the SDK:
The ConnectedThingClient now releases all resources on shutdown instead of on destruction. An exception is now thrown when more than one client tries to enter the started state.
Shutdown is now virtual so that it can be overridden.
The SteamSensor example now has a logging configuration file that uses the Apache log4net. It also supports TwApiException.
All references to ThingWorx logging have been removed. However, for customers who may still be using it, the class, com.thingworx.common.logging, has been retained.
Minor changes to build for .NET Core and standard .NET frameworks.
This topic includes the following information:
Installing log4net
To install log4net:
1. To add the log4net package to your project, use the Visual Studio UI to search for it and install it.
2. In your project, add a new file called log4net.config. Set the properties for it by right-clicking the file in Visual Studio and selecting Properties in the pop-up menu.
3. Set the Copy to Output Directory field in the file properties to Copy Always. This setting ensures that the configuration file is copied to the bin directory when you build and run your application.
4. Open the log4net.config file and add the appenders that you require for the application logs. Appenders tell log4net where to send the logs. The most often used appenders are RollingFileAppender and ConsoleAppender, which are used in the following example:

<log4net>
<root>
<level value="ALL" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
<appender name="console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %logger - %message%newline" />
</layout>
</appender>
<appender name="file" type="log4net.Appender.RollingFileAppender">
<file value="myapp.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>
</log4net>
To view log statements in the Debug window of Visual Studio, add the DebugAppender. If you are using a console appender, consider using the ColoredConsoleAppender. Errors appear in red, while DEBUG messages appear in green and paths in white.
5. Add the following line to the end of your AssemblyInfo.cs file (Properties section of a project):

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]
* 
The log4net.config file must be present in the default directory of your installed application.
How to Use log4net with .NET Core
There is another way to bootstrap the log4net services in the .NET SDK. You have already learned the simplest way: include it in your AssemblyInfo.cs file, as described in the previous section. This method is the same as in previous releases of the .NET SDK.
However, the AssemblyInfo.cs method does not work in .NET Core. Here, log4net must be started manually. An example of manually starting log4net is provided in the sample file SteamSensorClient.cs, where the following lines add log4net if .NET Core is in use:
#if TW_DOTNET_CORE
var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
string logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "log4net.config");
var ret = XmlConfigurator.Configure(logRepository,new FileInfo(logFilePath));
#endif
To use this code to manually start logging, you must define TW_DOTNET_CORE before building the steam sensor example, as shown here:
Or you can just paste the #if ... #endif code shown above into your application.
The SteamSensorClient.cs example shows how to set up logging in .NET Core, where App.config is not supported:

#if TW_DOTNET_CORE
var logRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
string logFilePath = Path.Combine(Directory.GetCurrentDirectory(), "log4net.config");
var ret = XmlConfigurator.Configure(logRepository,new FileInfo(logFilePath));
#endif
As far as the available log4net.config configurations, the .NET SDK provides examples of console logging and rolling file logging that were provided by previous versions of the SDK. There are many other logging methods provided by log4net. Refer to the Apache log4net documentation at https://logging.apache.org/log4net/.
Logging Levels
You may assign levels to loggers. Levels are instances of the log4net.Core.Level class. Log4net has fewer log levels than the ThingWorx Edge C SDK. The following logging levels are defined in log4net, shown here in descending order of verbosity and ascending order of priority:
1. all (logs everything)
2. debug
3. info
4. warn
5. error
6. fatal
7. off (do not log anything)
Note that TRACE level logging is not supported. All C SDK log events for TRACE and DEBUG have been mapped to log4net’s debug level. This includes any verbose logging from the API call twLogger_SetIsVerbose() in the C SDK. All of this information now passes through the log4net debug log level.
Choosing a particular logging level for an application also includes any messages that are written out at a lower level. For example, if the logging level for an application is set to warn, then the error and fatal levels are also written to the log.
Example 2. Warning, Info, Error, and Fatal Log Messages
Consider the following examples:
This example writes a warning message that logs a message with properties:
LoggerFactory.Log(LOG, TraceEventType.warn,
"Invalid data was entered");
Log(TraceSource tracer, TraceEventType eventType,
string format, params object[] args)
This example writes an information log message:
LoggerFactory.Log(LOG, TraceEventType.infp,
"Thing {0} started at {1}", thing.getName(), DateTime.Now);
This example writes a warning message and logs a message with an exception:
LoggerFactory.Log(LOG, TraceEventType.warn,
"Thing {0} has exited with code {1}", thing.getName(), code);
Log(TraceSource tracer, TraceEventType eventType, string message,
Exception x)
This example writes an error message:
LoggerFactory.Log(LOG, TraceEventType.error,
"SteamSensor exited.", x);
This example writes a fatal message that logs only exceptions:
LoggerFactory.Log(LOG, TraceEventType.fatal,
"Memory overrun, exiting", x);
Log(TraceSource tracer, TraceEventType eventType,
Exception x)
Rotating Logs with log4net
The log4net logging capabilities include log rotation based on file age and file size. You can use log4net with a RollingFileAppender. For details about the RollingFileAppender class, refer to https://logging.apache.org/log4net/release/sdk/html/T_log4net_Appender_RollingFileAppender.htm. You can also find an example for rotating by size and date on the Apache log4net Config Examples page, at https://logging.apache.org/log4net/release/config-examples.html. Once the page appears, scroll down the page until you find RollingFileAppender. The page is organized alphabetically, so the example is about 2/3 of the way down the page.
Was this helpful?