Example #1
0
        static void Main(string[] args)
        {
            // Log configuration should be setup on client app side, so I left this here.
            // I don't like an idea to add Serilog packages to this project, but I see no other way at the moment.
            // Every so called sink (ColoredConsole, File, etc) is a standalone package, so configuration must be done here.
            // There is another aproach - a congig file. If we go with config file, then probably we can avoid issue above.

            /* we cannot configure Serilog inside client app cuz we are going to hide log provider from end users behind our wrapper
             * var cfg = new LoggerConfiguration()
             *  .Enrich.FromLogContext()
             *  .MinimumLevel.Debug()
             *  .WriteTo.ColoredConsole(
             *      LogEventLevel.Verbose,
             *      "{NewLine}{Timestamp:HH:mm:ss} [{Level}] ({CorrelationToken}) {Message}{NewLine}{Exception}");
             */

            var configuration = new ConfigurationBuilder()
                                .AddJsonFile("appsettings.json")
                                .Build();

            using (ILogger logger = new SerilogLogger(configuration))
            {
                //Simple log entry
                logger.Debug("Hello World!");

                //Parameterized log entry
                var quota = 100;
                var user  = new { FirstName = "John", LastName = "Walter" };
                logger.Write(LogLevel.Warning, "Disk quota {Quota} MB exceeded by {User}", quota, user);

                //Exception handling
                var myDataObject = new { Property1 = "Value1", Property2 = "Value2", Property3 = "Value3" };
                try
                {
                    int x = 0;
                    int y = 10 / x;
                }
                catch (Exception ex)
                {
                    logger.Fatal("Got an exception for {MyDataObject}", ex, myDataObject);
                }
            }

            Console.ReadKey();
        }
Example #2
0
        private void PerformLog(LogEntry logEntry)
        {
            if (DiagnosticContext == null || SerilogLogger == null)
            {
                throw new InvalidOperationException($"Configure asp.net core & serilog using https://github.com/serilog/serilog-aspnetcore");
            }

            bool isRequestLogEntry = false;

            if (logEntry.LogData.Any(ld => ld.Key == nameof(IRequestInformationProvider.DisplayUrl)) && HttpContextAccessor.HttpContext != null)
            {
                isRequestLogEntry = true;

                HttpContext httpContext = HttpContextAccessor.HttpContext;

                IUserInformationProvider userInformationProvider = httpContext.RequestServices.GetRequiredService <IUserInformationProvider>();
            }

            var keyValues = logEntry.LogData.Select(ld =>
            {
                string k = ld.Key;

                if (k == nameof(IRequestInformationProvider.HttpMethod) ||
                    k == nameof(IRequestInformationProvider.DisplayUrl) ||
                    k == "ResponseStatusCode" ||
                    ld.Value == null)
                {
                    return(Key: null, Value: null);  // Already being logged by serilog!
                }
                string v = null;

                if (ld.Value is string valueAsStr)
                {
                    v = valueAsStr;
                }

                if (k == "ClientLogs" || k == "OperationArgs")
                {
                    v = Formatter.Serialize(ld.Value);
                }
                else
                {
                    v = ld.Value.ToString();
                }

                return(Key: k, Value: v);
            })
                            .Where(d => d.Key != null)
                            .ToList();

            keyValues.Add((Key: nameof(LogEntry.MemoryUsage), Value: logEntry.MemoryUsage.ToString()));

            if (logEntry.AppServerDateTime.HasValue)
            {
                keyValues.Add((Key: nameof(LogEntry.AppServerDateTime), Value: logEntry.AppServerDateTime.ToString()));
            }

            keyValues.Add((Key: nameof(LogEntry.Severity), Value: logEntry.Severity));
            keyValues.Add((Key: nameof(LogEntry.Message), Value: logEntry.Message));

            if (logEntry.Id.HasValue)
            {
                keyValues.Add((Key: nameof(LogEntry.Id), Value: logEntry.Id.ToString()));
            }

            if (logEntry.AppServerThreadId.HasValue)
            {
                keyValues.Add((Key: nameof(LogEntry.AppServerThreadId), Value: logEntry.AppServerThreadId.ToString()));
            }

            foreach (var(Key, Value) in keyValues.OrderBy(kv => kv.Key))
            {
                DiagnosticContext.Set(Key, Value);
            }

            if (isRequestLogEntry == true)
            {
                LogData userAgent = logEntry.LogData.FirstOrDefault(ld => ld.Key == nameof(IRequestInformationProvider.UserAgent));

                if (userAgent != null)
                {
                    DiagnosticContext.Set("UserAgent", userAgent.Value);
                }
            }
            else
            {
                Exception ex = null;

                try
                {
                    var(Key, Value) = keyValues.ExtendedSingleOrDefault("Finding ExceptionTypeAssemblyQualifiedName...", kv => kv.Key == "ExceptionTypeAssemblyQualifiedName");

                    if (!string.IsNullOrEmpty(Value))
                    {
                        ex = (Exception)Activator.CreateInstance(Type.GetType(Value) ?? throw new InvalidOperationException($"{Value} could not be found"), args: new object[] { logEntry.Message });
                    }
                }
                catch { }

                LogEventLevel level = logEntry.Severity switch
                {
                    "Information" => LogEventLevel.Information,
                    "Warning" => LogEventLevel.Warning,
                    "Error" => LogEventLevel.Error,
                    "Fatal" => LogEventLevel.Fatal,
                    _ => LogEventLevel.Debug,
                };

                SerilogLogger.Write(level, ex?.Message ?? logEntry.Message);
            }
        }