static LogEvent ReadFromJObject(int lineNumber, JObject jObject) { var timestamp = GetRequiredTimestampField(lineNumber, jObject, ClefFields.Timestamp); string messageTemplate; if (!TryGetOptionalField(lineNumber, jObject, ClefFields.MessageTemplate, out messageTemplate)) { string message; if (!TryGetOptionalField(lineNumber, jObject, ClefFields.Message, out message)) { throw new InvalidDataException($"The data on line {lineNumber} does not include the required `{ClefFields.MessageTemplate}` or `{ClefFields.Message}` field."); } messageTemplate = MessageTemplateSyntax.Escape(message); } var level = LogEventLevel.Information; if (TryGetOptionalField(lineNumber, jObject, ClefFields.Level, out string l)) { level = (LogEventLevel)Enum.Parse(typeof(LogEventLevel), l); } Exception exception = null; if (TryGetOptionalField(lineNumber, jObject, ClefFields.Exception, out string ex)) { exception = new TextException(ex); } var unrecognized = jObject.Properties().Where(p => ClefFields.IsUnrecognized(p.Name)); // ReSharper disable once PossibleMultipleEnumeration if (unrecognized.Any()) { // ReSharper disable once PossibleMultipleEnumeration var names = string.Join(", ", unrecognized.Select(p => $"`{p.Name}`")); throw new InvalidDataException($"{names} on line {lineNumber} are unrecognized."); } var parsedTemplate = Parser.Parse(messageTemplate); var renderings = Enumerable.Empty <Rendering>(); if (jObject.TryGetValue(ClefFields.Renderings, out JToken r)) { var renderedByIndex = r as JArray; if (renderedByIndex == null) { throw new InvalidDataException($"The `{ClefFields.Renderings}` value on line {lineNumber} is not an array as expected."); } renderings = parsedTemplate.Tokens .OfType <PropertyToken>() .Where(t => t.Format != null) .Zip(renderedByIndex, (t, rd) => new Rendering(t.PropertyName, t.Format, rd.Value <string>())) .ToArray(); } var properties = jObject .Properties() .Where(f => !ClefFields.All.Contains(f.Name)) .Select(f => { var name = ClefFields.Unescape(f.Name); var renderingsByFormat = renderings.Where(rd => rd.Name == name); return(PropertyFactory.CreateProperty(name, f.Value, renderingsByFormat)); }) .ToList(); string eventId; if (TryGetOptionalField(lineNumber, jObject, ClefFields.EventId, out eventId)) // TODO; should support numeric ids. { properties.Add(new LogEventProperty("@i", new ScalarValue(eventId))); } return(new LogEvent(timestamp, level, exception, parsedTemplate, properties)); }
static LogEvent ReadFromJObject(int lineNumber, JObject jObject) { var timestamp = GetRequiredTimestampField(lineNumber, jObject, ClefFields.Timestamp); string messageTemplate; if (TryGetOptionalField(lineNumber, jObject, ClefFields.MessageTemplate, out var mt)) { messageTemplate = mt; } else if (TryGetOptionalField(lineNumber, jObject, ClefFields.Message, out var m)) { messageTemplate = MessageTemplateSyntax.Escape(m); } else { messageTemplate = null; } var level = LogEventLevel.Information; if (TryGetOptionalField(lineNumber, jObject, ClefFields.Level, out string l)) { level = (LogEventLevel)Enum.Parse(typeof(LogEventLevel), l); } Exception exception = null; if (TryGetOptionalField(lineNumber, jObject, ClefFields.Exception, out string ex)) { exception = new TextException(ex); } var parsedTemplate = messageTemplate == null ? new MessageTemplate(Enumerable.Empty <MessageTemplateToken>()) : Parser.Parse(messageTemplate); var renderings = Enumerable.Empty <Rendering>(); if (jObject.TryGetValue(ClefFields.Renderings, out JToken r)) { var renderedByIndex = r as JArray; if (renderedByIndex == null) { throw new InvalidDataException($"The `{ClefFields.Renderings}` value on line {lineNumber} is not an array as expected."); } renderings = parsedTemplate.Tokens .OfType <PropertyToken>() .Where(t => t.Format != null) .Zip(renderedByIndex, (t, rd) => new Rendering(t.PropertyName, t.Format, rd.Value <string>())) .ToArray(); } var properties = jObject .Properties() .Where(f => !ClefFields.All.Contains(f.Name)) .Select(f => { var name = ClefFields.Unescape(f.Name); var renderingsByFormat = renderings.Where(rd => rd.Name == name); return(PropertyFactory.CreateProperty(name, f.Value, renderingsByFormat)); }) .ToList(); string eventId; if (TryGetOptionalField(lineNumber, jObject, ClefFields.EventId, out eventId)) // TODO; should support numeric ids. { properties.Add(new LogEventProperty("@i", new ScalarValue(eventId))); } return(new LogEvent(timestamp, level, exception, parsedTemplate, properties)); }