Code Monkey home page Code Monkey logo

daenet.common.logging.sql's Introduction

SQL Logger

Implementation of Logging in SQL Server Database for Dot Net Core Applications.

This repository contains Implementation of ASP.NET Core Logger Provider in SQL Server Database. It enables you to log the information in SQL Database table. For general ASP.NET Core logger implementation, visit here.

Installation

Install the Daenet.Common.Logging.Sql NuGet Package in your application.

Configuration

The SqlServerLogger needs to be configured and initialized.

ASP.NET Core Web Application

public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
            .ConfigureLogging((hostingContext, logging) =>
            {
                var loggerSection = hostingContext.Configuration.GetSection("Logging");
                logging.AddConfiguration(loggerSection);
                logging.AddConsole();
                logging.AddDebug();
                logging.AddSqlServerLogger((sett) =>
                {
                    sett.SetSqlServerLoggerSettings(loggerSection);
                });
            })
                .Build();
    }

Console Application

  public IConfigurationRoot Configuration;
  var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
  Configuration = builder.Build();

  ILoggerFactory loggerFactory = new LoggerFactory().AddSqlServerLogger(Configuration.GetSection("Logging"));
  ILogger logger = loggerFactory.CreateLogger<SqlServerLoggerTests>();

In the appsettings.json, the SqlProvider part needs to be added to Logging.

{
  "Logging": {
    "IncludeScopes": true,
    "Debug": {
      "LogLevel": {
        "Default": "Information"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "SqlProvider": {
      "LogLevel": {
        "Default": "Information"
      },
      "ConnectionString": "",
      "TableName": "SqlLog",
      "BatchSize": 1,
      "InsertTimerInSec": 60,
      "IncludeExceptionStackTrace": false,
      "IgnoreLoggingErrors": false,
      "ScopeSeparator": "=>"
    }
  }
}

LogLevel configuration are done on global and logger level see Introduction to Logging in ASP.NET Core

IncludeScope flag is used when the logging is to be done inside one particular scope. IncludeScope when set to true, and initialized inside code with beginScope("scopeStatement") adds scope id to every logged statement which is added to database under column "Scope". Following example illustrates using scope in logging when IncludeScopes flag is set to true.

 using (m_Logger.BeginScope($"Scope Begins : {Guid.NewGuid()}"))
 {
   //Here log something
 }

This will add "Scope begins : new hexadecimal guid" for every object instance of the class where scope is began.

ConnectionString is ADO.NET connection string for SQL authentication.

TableName is name of the table where logger should log.

BatchSize Decides when to write messages to the database. If BatchSize > 1 then we fill a List and wait till list count reaches BatchSize or Insert to DB is triggered by InsertTimerInSec. If BatchSize > 1 writing the data to db is async.

InsertTimerInSec Time elapsed when logger writes to table even BatchSize isn't reached.

(REMOVED in 1.0.7.2) CreateTblIfNotExist flag when set to true, gives the logger ability to create the table of table name that is provided in configuration in case it is not already available in database. This flag is useful while testing the logger in development environment.

IncludeExceptionStackTrace flag is currently not implemented and complete exception is logged in table regardless of this flag.

IgnoreLoggingErrors flag is to decide if the application should fail if an exception occurs on logging. When set to false, the logger at the moment logs these errors in debug console. **WARNING: Only works if BatchSize = 1

Database Configuration

To log the error in SQL database, A table must be present in database with predefined column format. Following columns are filled by logger -

  • Id - Unique id of each entry, automatically incremented
  • EventId - Event Id of each log.
  • Type - Log level
  • Scope - Scope information if scoping is enabled and used
  • Message - Log message
  • Exception - Complete exception in case of error
  • TimeStamp - Timestamp of log
  • CategoryName - Namespace from where the log is logged

Following query will create a new table in SQL Database with above parameters, and should be used as a reference query for default format.

CREATE TABLE [dbo].[YourTableName](
       [Id] [bigint] IDENTITY(1,1) NOT NULL,
       [EventId] [int] NULL,
       [Type] [nvarchar](15) NOT NULL,
       [Scope] [nvarchar](MAX) NULL,
       [Message] [nvarchar](max) NOT NULL,
       [Exception] [nvarchar](max) NULL,
       [TimeStamp] [datetime] NOT NULL,
       [CategoryName] [nvarchar] (max) NULL,
CONSTRAINT [PK_YourTableName] PRIMARY KEY CLUSTERED 
(
       [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

Logging Parameters to database

It's possible to log parameters to database, too. In this example we want to log the RequestId and the scope to the database. For this to work, you have to create the columns of course.

This configuration has to be apppended to the SqlProvider section in Logging.

Here is an example of how to log the 2 .NET Core internal logging parameters. You can extend this, with the parameters you use in your logging. A good example here is {method} for logging the method name in a general way.

"ScopeColumnMapping": {
        "RequestId": "RequestId",
        "SCOPEPATH": "Scope"
      }

Custom SQL Logging Format

It is also possible to use your own custom logging format by providing loggingFormatter

daenet.common.logging.sql's People

Contributors

ddobric avatar dependabot[bot] avatar hvetter-de avatar poleindraneel avatar prnn avatar rnebhuth avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

daenet.common.logging.sql's Issues

Create Mapper

We need a mapping for mapping the following things:
Keys in Scope Dictionary TO Column
ColumnA TO ColumnB

We need this for compatibility reasons, for example the following table has to work, too.

CREATE TABLE [dbo].[TMon_Test](
       [Id] [bigint] IDENTITY(1,1) NOT NULL,
       [EventId] [int] NULL,
       [TracingLevel] [int] NULL,
       [Type] [nvarchar](3) NOT NULL,
       [Message] [nvarchar](max) NOT NULL,
       [Exception] [nvarchar](max) NULL,
       [TimeStamp] [datetime] NOT NULL,
       [Source] [nvarchar](255) NOT NULL,
       [Param0] [nvarchar](max) NULL,
       [Param1] [nvarchar](max) NULL,
       [Param2] [nvarchar](max) NULL,
       [Param3] [nvarchar](max) NULL,
       [Param4] [nvarchar](max) NULL,
       [Param5] [nvarchar](max) NULL,
       [Param6] [nvarchar](max) NULL,
       [Param7] [nvarchar](max) NULL,
       [Param8] [nvarchar](max) NULL,
       [Param9] [nvarchar](max) NULL,
       [Scope] [nvarchar](max) NULL,
 CONSTRAINT [PK_TMon_ETest] PRIMARY KEY CLUSTERED 
(
       [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO 

Scope improvements

We want to make improvements to the scope.
In many applications we have an ActivityId, this ActivityIds needs to be saved in an own column.

The user can pass a Dictionary<string, object> to the BeginScope method.
This is saved to the scope, when the Logger logs we iterate trough the scope and just .ToString() the value.
We need to add a check here if we are dealing with a dictionary.
If we are dealing with a dictionary following should happen:

  • Map Keys to the columns and insert the value

Evaluate Switches/LogLevel

  • Check if Switches are working
  • Check how other Providers handle the Switches
  • Implement Switches/LogLevel

Think they removed Switches and changed it to LogLevel

The Sql Log is part of a business transaction.

If the Business Code opens transaction scope and then logs in this scope, the logs are part of the transactions. which is a problem in two ways.

  1. If the business transaction is rolled back then logs are, too.
  2. There can be a problem with the distributed transaction manager
    "System.PlatformNotSupportedException: This platform does not support distributed transactions."

Rename Switches to LogLevel

This should improve compability of SqlLogger with microsoft ILogger implementations, for example ConsoleLogger.

Implement AdditionalProperties

AdditionalProperties can be added at Logger init.
Every time logger logs, the AdditionalProperties are added. They will be written to the mapping columns.

AdditionalProperties is a Dictionary<string, string>

2 possibilities:

  1. All AdditionalProperties are written to one column (Column Name: AdditionalProperties)
  2. Every value of AdditionalProperties is written to the key column

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.