Author : HASSAN MD TAREQ

Console

Installation

Install-Package Serilog
Install-Package Serilog.Sinks.Console
Install-Package Serilog.Settings.Configuration

Using appsettings.json for Configuration
appsettings.json

{
    "Serilog": {
      "Using": ["Serilog.Sinks.Console"],
      "MinimumLevel": "Debug",
      "WriteTo": [
        { 
            "Name": "Console",
            "Args": {
              "outputTemplate": "",
              "theme": ""
            }
        },
      ]
    }
}

See: Console sink github wiki

outputTemplate for Console Sink
appsettings.json

{
    "Serilog": {
      "Using": ["Serilog.Sinks.Console"],
      "MinimumLevel": "Debug",
      "WriteTo": [
        { 
            "Name": "Console",
            "Args": {
              "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}",
            }
        },
      ]
    }
}

See: Constructing outputTemplate

Themes

  • The sink will colorize output by default

appsettings.json

{
    "Serilog": {
      "Using": ["Serilog.Sinks.Console"],
      "MinimumLevel": "Debug",
      "WriteTo": [
        { 
            "Name": "Console",
            "Args": {
              "theme": "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console"
            }
        },
      ]
    }
}

See: Using theme

File

Installation

Install-Package Serilog
Install-Package Serilog.Sinks.File

Using appsettings.json for Configuration

  • outputTemplate
  • formatter: log as json
  • path: log file path
  • fileSizeLimitBytes : default: 1 GB, use null for unlimited
  • rollOnFileSizeLimit : default: true
  • rollingInterval : default: “Day”
  • retainedFileCountLimit : default: 31 days, use null for unlimited
  • shared: to enable multi-process shared log files, default: false

appsettings.json

{
    "Serilog": {
      "Using": ["Serilog.Sinks.File"],
      "MinimumLevel": "Debug",
      "WriteTo": [
        { 
            "Name": "File",
            "Args": {
              "outputTemplate": "",
              "formatter": ""
              "path": "",
              "fileSizeLimitBytes": "",
              "rollOnFileSizeLimit": "",
              "rollingInterval": "",
              "retainedFileCountLimit": "",
              "shared": "",
            }
        },
      ]
    }
}

Notes :

Logging as JSON

Install-Package Serilog.Formatting.Compact

appsettings.json

{
    "Serilog": {
      "Using": ["Serilog.Sinks.File"],
      "MinimumLevel": "Debug",
      "WriteTo": [
        { 
            "Name": "File",
            "Args": {
              "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact"
            }
        },
      ]
    }
}

See: Log event properties when using CompactJsonFormatter

Using Async Sink to Improve Performance

  • asynchronous wrapper for sinks
  • reduce the overhead of logging calls by delegating work to a background thread
  • suited to non-batching sinks that may be affected by I/O bottlenecks i.e. File sink
  • many of the network-based sinks (Seq, Elasticsearch …) already perform asynchronous batching natively and do not benefit from this wrapper

Install

Install-Package Serilog.Sinks.Async

appsettings.json

{
  "Serilog": {
    "WriteTo": [{
      "Name": "Async",
      "Args": {
        "configure": [
            {
              "Name": "",
              "Args" {"path": "", "outputTemplate": ""}
            }
        ]
      }
    }]
  }
}

seq

  • Seq is a centralized log server for ingesting and querying structured log events
  • See: Seq official doc

Installation

Install-Package Serilog
Install-Package Serilog.Sinks.Seq
Install-Package Serilog.Formatting.Compact
Install-Package Serilog.AspNetCore -DependencyVersion Highest

Using appsettings.json for Configuration

{
  "Serilog": {
    "WriteTo": [
      { 
        "Name": "Seq",
        "Args": { 
          "serverUrl": "http://localhost:5341",
          "compact" : true,
        } 
      }
    ]
  }
}

See: Seq official doc for using Serilog

Running Seq in docker

docker volume create seq  
docker run --name seq -p 5341:5341 -p 80:80 -e ACCEPT_EULA=Y --mount source=seq,target=/data -d datalust/seq:latest

Goto: localhost

Change port

docker stop seq
docker rm seq
docker run --name seq -p 5341:5341 -p 81:80 -e ACCEPT_EULA=Y --mount source=seq,target=/data -d datalust/seq:latest

Goto: localhost:81

ELK

ELK = ElasticSearch, Logstash, Kibana

Docker ELK

  • Docker Hub: https://hub.docker.com/r/sebp/elk/
  • Documentation: https://elk-docker.readthedocs.io/
docker pull sebp/elk

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 --name elk -d sebp/elk

Serilog.Sinks.Elasticsearch

Installation

Install-Package Serilog
Install-Package Serilog.Sinks.ElasticSearch
  • Nuget package for sink is required where logging method is called (Logger class or client of logger class)
  • Additional package for ASP.NET Core: PM> Install-Package Serilog.AspNetCore -DependencyVersion Highest

Using appsettings.json for Configuration
appsettings.json

{
  "Serilog": {
    "WriteTo": [{ 
        "Name": "Elasticsearch", 
        "Args": { 
          "nodeUris": "http://localhost:9200;http://remotehost:9200/",
          "indexFormat": "custom-index-{0:yyyy.MM}",
          "templateName": "myCustomTemplate",
          "typeName": "myCustomLogEventType",
          "pipelineName": "myCustomPipelineName",
          "batchPostingLimit": 50,
          "period": 2000,
          "inlineFields": true,
          "minimumLogEventLevel": "Warning",
          "bufferBaseFilename":  "C:/Temp/LogDigipolis/docker-elk-serilog-web-buffer",
          "bufferFileSizeLimitBytes": 5242880,
          "bufferLogShippingInterval": 5000,
          "connectionGlobalHeaders" :"Authorization=Bearer SOME-TOKEN;OtherHeader=OTHER-HEADER-VALUE",
          "connectionTimeout": 5,
          "emitEventFailure": "WriteToSelfLog",
          "queueSizeLimit": "100000",
          "autoRegisterTemplate": true,
          "autoRegisterTemplateVersion": "ESv2",
          "overwriteTemplate": false,
          "registerTemplateFailure": "IndexAnyway",
          "deadLetterIndexName": "deadletter-{0:yyyy.MM}",
          "numberOfShards": 20,
          "numberOfReplicas": 10,
          "formatProvider": "My.Namespace.MyFormatProvider, My.Assembly.Name",
          "connection": "My.Namespace.MyConnection, My.Assembly.Name",
          "serializer": "My.Namespace.MySerializer, My.Assembly.Name",
          "connectionPool": "My.Namespace.MyConnectionPool, My.Assembly.Name",
          "customFormatter": "My.Namespace.MyCustomFormatter, My.Assembly.Name",
          "customDurableFormatter": "My.Namespace.MyCustomDurableFormatter, My.Assembly.Name",
          "failureSink": "My.Namespace.MyFailureSink, My.Assembly.Name"
        }       
    }]
  }
}

AutoRegisterTemplate

var loggerConfig = new LoggerConfiguration()
    .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200") ){
             AutoRegisterTemplate = true,
             AutoRegisterTemplateVersion = AutoRegisterTemplateVersion.ESv6
     });

Viewing Log in Elasticsearch

  • Index search: [http://localhost:9200/foo/_search?size=1000](http://localhost:9200/foo/_search?size=1000)
  • Deleting index in kibana devtools: DELETE _all