Пример #1
0
        public void DistinctHashesAreComputed()
        {
            var h1 = EventIdHash.Compute("Template 1");
            var h2 = EventIdHash.Compute("Template 2");

            Assert.NotEqual(h1, h2);
        }
Пример #2
0
        public void HashingIsConsistent()
        {
            var h1 = EventIdHash.Compute("Template 1");
            var h2 = EventIdHash.Compute("Template 1");

            Assert.Equal(h1, h2);
        }
        public void AMinimalEventIsValidJson()
        {
            var jobject = AssertValidJson(log => log.Information("One {Property}", 42));

            JToken m;

            Assert.True(jobject.TryGetValue("@m", out m));
            Assert.Equal("One 42", m.ToObject <string>());

            JToken i;

            Assert.True(jobject.TryGetValue("@i", out i));
            Assert.Equal(EventIdHash.Compute("One {Property}").ToString("x8"), i.ToObject <string>());
        }
        /// <summary>
        /// Format the log event into the output.
        /// </summary>
        /// <param name="logEvent">The event to format.</param>
        /// <param name="output">The output.</param>
        /// <param name="valueFormatter">A value formatter for <see cref="LogEventPropertyValue"/>s on the event.</param>
        public void FormatEvent(LogEvent logEvent, TextWriter originalOutput, JsonValueFormatter valueFormatter)
        {
            if (logEvent == null)
            {
                throw new ArgumentNullException(nameof(logEvent));
            }
            if (originalOutput == null)
            {
                throw new ArgumentNullException(nameof(originalOutput));
            }
            if (valueFormatter == null)
            {
                throw new ArgumentNullException(nameof(valueFormatter));
            }

            // wrap the originally text writer in one that can count the number of characters written
            var output = new CountingTextWriter(originalOutput);

            /*
             * 'timestamp', 'message', 'severity' and 'exception' are well-known
             * properties that Stackdriver will use to display and analyse your
             * logs correctly.
             */

            // TIMESTAMP
            output.Write("{\"timestamp\":\"");
            output.Write(logEvent.Timestamp.UtcDateTime.ToString("O"));

            // MESSAGE
            output.Write("\",\"message\":");
            var message = logEvent.MessageTemplate.Render(logEvent.Properties);

            JsonValueFormatter.WriteQuotedJsonString(message, output);

            // FINGERPRINT
            output.Write(",\"fingerprint\":\"");
            var id = EventIdHash.Compute(logEvent.MessageTemplate.Text);

            output.Write(id.ToString("x8"));
            output.Write('"');

            // SEVERITY
            // https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
            output.Write(",\"severity\":\"");
            var severity = StackDriverLogLevel.GetSeverity(logEvent.Level);

            output.Write(severity);
            output.Write('\"');

            // EXCEPTION
            if (logEvent.Exception != null)
            {
                output.Write(",\"exception\":");
                JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output);
            }

            // Serilog Message Template
            if (_includeMessageTemplate)
            {
                // Capitalized to match default Serilog JsonFormatter
                output.Write(",\"MessageTemplate\":");
                JsonValueFormatter.WriteQuotedJsonString(logEvent.MessageTemplate.Text, output);
            }

            // Custom Properties passed in by code logging
            foreach (var property in logEvent.Properties)
            {
                var name = property.Key;
                if (name.Length > 0 && name[0] == '@')
                {
                    // Escape first '@' by doubling
                    name = '@' + name;
                }

                WriteKeyValue(output, valueFormatter, name, property.Value);
            }

            output.Write('}');
            output.WriteLine();             // finish the log line

            // if we have blown the limit of a single stackdriver line (which means that error reporting won't parse
            // it correctly for instance) - then log that fact out too so we can adjust the logging and fix the problem
            if (_checkForPayloadLimit && (output.CharacterCount * 4) >= STACKDRIVER_ENTRY_LIMIT_BYTES)
            {
                string text            = "An attempt was made to write a log event to stackdriver that exceeds StackDriver Entry length limit - check logs for partially parsed entry just prior to this and fix at source";
                var    tooLongLogEvent = new LogEvent(
                    logEvent.Timestamp, LogEventLevel.Fatal, null,
                    new MessageTemplate(text, new MessageTemplateToken[] { new TextToken(text) }),                     // this is actually what gets rendered
                    new List <LogEventProperty>()
                    );
                FormatEvent(tooLongLogEvent, output, valueFormatter);
            }
        }
Пример #5
0
 public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
 {
     logEvent.AddOrUpdateProperty(new LogEventProperty("EventId", new ScalarValue(EventIdHash.Compute(logEvent.MessageTemplate.Text))));
 }
Пример #6
0
        /// <summary>
        /// Format the log event into the output.
        /// </summary>
        /// <param name="logEvent">The event to format.</param>
        /// <param name="output">The output.</param>
        /// <param name="valueFormatter">A value formatter for <see cref="LogEventPropertyValue"/>s on the event.</param>
        public static void FormatEvent(LogEvent logEvent, TextWriter output, JsonValueFormatter valueFormatter)
        {
            if (logEvent == null)
            {
                throw new ArgumentNullException(nameof(logEvent));
            }
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }
            if (valueFormatter == null)
            {
                throw new ArgumentNullException(nameof(valueFormatter));
            }

            /*
             * 'timestamp', 'message', 'severity' and 'exception' are well-known
             * properties that Stackdriver will use to display and analyse your
             * logs correctly.
             */

            output.Write("{\"timestamp\":\"");
            output.Write(logEvent.Timestamp.UtcDateTime.ToString("O"));

            output.Write("\",\"message\":");
            var message = logEvent.MessageTemplate.Render(logEvent.Properties);

            JsonValueFormatter.WriteQuotedJsonString(message, output);

            output.Write(",\"fingerprint\":\"");
            var id = EventIdHash.Compute(logEvent.MessageTemplate.Text);

            output.Write(id.ToString("x8"));
            output.Write('"');

            // Log severity as understood by Stackdriver:
            // https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
            output.Write(",\"severity\":\"");
            switch (logEvent.Level)
            {
            case LogEventLevel.Debug:
            case LogEventLevel.Verbose:     // Stackdriver doesn't have a Verbose level
                output.Write("DEBUG");
                break;

            case LogEventLevel.Warning:
                output.Write("WARNING");
                break;

            case LogEventLevel.Error:
                output.Write("ERROR");
                break;

            case LogEventLevel.Fatal:
                output.Write("CRITICAL");
                break;

            case LogEventLevel.Information:
                output.Write("INFO");
                break;

            default:
                output.Write("DEFAULT");
                break;
            }
            output.Write('\"');

            if (logEvent.Exception != null)
            {
                output.Write(",\"exception\":");
                JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output);
            }

            foreach (var property in logEvent.Properties)
            {
                var name = property.Key;
                if (name.Length > 0 && name[0] == '@')
                {
                    // Escape first '@' by doubling
                    name = '@' + name;
                }

                output.Write(',');
                JsonValueFormatter.WriteQuotedJsonString(name, output);
                output.Write(':');
                valueFormatter.Format(property.Value, output);
            }

            output.Write('}');
        }