Developer Docs

Log handling in C#Bot server-side

Please note that no logging is currently output to file system.

Logging libraries

Currently, C#Bot uses the built-in library Microsoft.Extensions.Logging for logging.

Logging strategy

Logging configuration files

To provide more options to configure the logging, C#Bot currently uses two configuration files for the logging functionality: appsettings.xml and appsettings.Development.xml.


The appsetting.xml file contains the configuration settings used in the production environment, and the following xml snippet shows how to set the default logging level to “Warning”.


The file can be located at serverside/src/appsettings.xml. You can use the protected regions in this file to make any changes necessary.


The appsettings.Development.xml file contains the configuration settings used in the development environment, and the following snippet shows how different logging levels are set.




The file can be located at serverside/src/appsettings.Development.xml.

To change these configurations, you need to turn on the protected region in this file and change them to the required level.


There are many ways to add logging configurations.

Currently, logging configuration in C#Bot is in the Logging section of appsettings files. The following example shows the contents of a typical appsettings.Development.xml file:




The Logging property can have LogLevel. The LogLevel property specifies the minimum level to log for selected categories. In the example, System and Microsoft categories log at Information level, and all others log at Debug level.

For information on implementing configuration providers, see Configuration in ASP.NET Core.

Log levels

Every log specifies a LogLevel value. The log level indicates the severity or importance. For example, you might write an Information log when a method ends normally and a Warning log when a method returns a 404 Not Found status code.

The following code creates Information and Warning logs:

public IActionResult GetById(string id)
    _logger.LogInformation(LoggingEvents.GetItem, "Getting item {Id}", id);
    var item = _todoRepository.Find(id);
    if (item == null)
        _logger.LogWarning(LoggingEvents.GetItemNotFound, "GetById({Id}) NOT FOUND", id);
        return NotFound();
    return new ObjectResult(item);

In the preceding code, the first parameter is the Log event ID. The second parameter is a message template with placeholders for argument values provided by the remaining method parameters. The method parameters are explained in the message template section later in this article.

Log methods that include the level in the method name (for example, LogInformation and LogWarning) are extension methods for ILogger. These methods call a Log method that takes a LogLevel parameter. You can call the Log method directly rather than one of these extension methods, but the syntax is relatively complicated. For more information, see ILogger and the logger extensions source code.

ASP.NET Core defines the following log levels, ordered here from lowest to highest severity:

Name Level Usage Example(s)
Trace 0 For information that’s typically valuable only for debugging. These messages may contain sensitive application data and so shouldn’t be enabled in a production environment. Disabled by default.  
Debug 1 For information that may be useful in development and debugging. Enable Debug level logs in production only when troubleshooting, due to the high volume of logs. Entering method Configure with flag set to true.
Information 2 For tracking the general flow of the app. These logs typically have some long-term value. Request received for path /api/todo
Warning 3 For abnormal or unexpected events in the app flow. These may include errors or other conditions that don’t cause the app to stop but might need to be investigated. Handled exceptions are a common place to use the Warning log level. FileNotFoundException for file quotes.txt
Error 4 For errors and exceptions that cannot be handled. These messages indicate a failure in the current activity or operation (such as the current HTTP request), not an app-wide failure. Cannot insert record due to duplicate key violation.
Critical 5 For failures that require immediate attention. data loss scenarios, out of disk space

Use the log level to control how much log output is written to a particular storage medium or display window. For example:

In Production

Logging at the Trace through Information levels produces a high-volume of detailed log messages. To control costs and not exceed data storage limits, log Trace through Information level messages to a high-volume, low-cost data store.

Logging at Warning through Critical levels typically produces fewer, smaller log messages. Therefore, costs and storage limits usually aren’t a concern, which results in greater flexibility of data store choice.

In Development

Log Warning through Critical messages to the console.

Add Trace through Information messages when troubleshooting.

The Log filtering section later in this article explains how to control which log levels a provider handles.

Example of writing logs in your code

public class AccountController : Controller
    private readonly ILogger<AccountController> _logger;
    public AccountController(
        ILogger<AccountController> logger)
        _logger = logger;
    public async Task<IActionResult> ExampleAction()
        catch (Exception e)

To see console logging output, open a command prompt in the project folder and run the following command:

dotnet run

Example of console logs

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:62555/api/todo/0
dbug: Microsoft.AspNetCore.Routing.Tree.TreeRouter[1]
      Request successfully matched the route with name 'GetTodo' and template 'api/Todo/{id}'.
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Update (TodoApi)' with id '089d59b6-92ec-472d-b552-cc613dfd625d' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ActionSelector[2]
      Action 'TodoApi.Controllers.TodoController.Delete (TodoApi)' with id 'f3476abe-4bd9-4ad3-9261-3ead09607366' did not match the constraint 'Microsoft.AspNetCore.Mvc.Internal.HttpMethodActionConstraint'
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action TodoApi.Controllers.TodoController.GetById (TodoApi)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method TodoApi.Controllers.TodoController.GetById (TodoApi) with arguments (0) - ModelState is Valid
info: TodoApi.Controllers.TodoController[1002]
      Getting item 0
warn: TodoApi.Controllers.TodoController[4000]
      GetById(0) NOT FOUND
dbug: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method TodoApi.Controllers.TodoController.GetById (TodoApi), returned result Microsoft.AspNetCore.Mvc.NotFoundResult.
info: Microsoft.AspNetCore.Mvc.StatusCodeResult[1]
      Executing HttpStatusCodeResult, setting HTTP status code 404
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action TodoApi.Controllers.TodoController.GetById (TodoApi) in 0.8788ms
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
      Connection id "0HL6L7NEFF2QD" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 2.7286ms 404

Was this article helpful?

Thanks for your feedback!

If you would like to tell us more, please click on the link below to send us a message with more details.







On this page

New to Codebots?

We know our software can be complicated, so we are always happy to have a chat if you have any questions.