protected virtual void WriteRenderingsValues(IGrouping <string, PropertyToken>[] tokensWithFormat, IReadOnlyDictionary <string, LogEventPropertyValue> properties, TextWriter output) { var rdelim = ""; foreach (var ptoken in tokensWithFormat) { output.Write(rdelim); rdelim = ","; output.Write("\""); output.Write(ptoken.Key); output.Write("\":["); var fdelim = ""; foreach (var format in ptoken) { output.Write(fdelim); fdelim = ","; output.Write("{"); var eldelim = ""; WriteJsonProperty("Format", format.Format, ref eldelim, output); var sw = new StringWriter(); MessageTemplateRenderer.RenderPropertyToken(format, properties, sw, _formatProvider, true, false); WriteJsonProperty("Rendering", sw.ToString(), ref eldelim, output); output.Write("}"); } output.Write("]"); } }
protected virtual void WriteRenderingsValues(IGrouping <string, PropertyToken>[] tokensWithFormat, IReadOnlyDictionary <string, LogEventPropertyValue> properties, TextWriter output) { var propertyDelimiter = ""; foreach (var propertyFormats in tokensWithFormat) { output.Write(propertyDelimiter); propertyDelimiter = ","; output.Write("\""); output.Write(propertyFormats.Key); output.Write("\":["); var formatDelimiter = ""; foreach (var format in propertyFormats) { output.Write(formatDelimiter); formatDelimiter = ","; output.Write("{"); var elementDelimiter = ""; WriteJsonProperty("Format", format.Format, ref elementDelimiter, output); var sw = new StringWriter(); MessageTemplateRenderer.RenderPropertyToken(format, properties, sw, _formatProvider, isLiteral: true, isJson: false); WriteJsonProperty("Rendering", sw.ToString(), ref elementDelimiter, output); output.Write("}"); } output.Write("]"); } }
/// <summary> /// Render the token to the output. /// </summary> /// <param name="properties">Properties that may be represented by the token.</param> /// <param name="output">Output for the rendered string.</param> /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param> public override void Render(IReadOnlyDictionary <string, LogEventPropertyValue> properties, TextWriter output, IFormatProvider formatProvider = null) { if (output == null) { throw new ArgumentNullException(nameof(output)); } MessageTemplateRenderer.RenderTextToken(this, output); }
public void PropertyTokenFormatsAreApplied(string template, string appliedFormat, string expected) { var eventTemplate = _messageTemplateParser.Parse(template); var properties = new Dictionary <string, LogEventPropertyValue> { ["Number"] = new ScalarValue(16) }; var output = new StringWriter(); MessageTemplateRenderer.Render(eventTemplate, properties, output, appliedFormat, CultureInfo.InvariantCulture); Assert.Equal(expected, output.ToString()); }
/// <summary> /// Format the log event into the output. /// </summary> /// <param name="logEvent">The event to format.</param> /// <param name="output">The output.</param> public void Format(LogEvent logEvent, TextWriter output) { if (logEvent == null) { throw new ArgumentNullException(nameof(logEvent)); } if (output == null) { throw new ArgumentNullException(nameof(output)); } foreach (var token in _outputTemplate.Tokens) { if (token is TextToken tt) { MessageTemplateRenderer.RenderTextToken(tt, output); continue; } var pt = (PropertyToken)token; if (pt.PropertyName == OutputProperties.LevelPropertyName) { var moniker = LevelOutputFormat.GetLevelMoniker(logEvent.Level, pt.Format); Padding.Apply(output, moniker, pt.Alignment); } else if (pt.PropertyName == OutputProperties.NewLinePropertyName) { Padding.Apply(output, Environment.NewLine, pt.Alignment); } else if (pt.PropertyName == OutputProperties.ExceptionPropertyName) { var exception = logEvent.Exception == null ? "" : logEvent.Exception + Environment.NewLine; Padding.Apply(output, exception, pt.Alignment); } else { // In this block, `writer` may be used to buffer output so that // padding can be applied. var writer = pt.Alignment.HasValue ? new StringWriter() : output; if (pt.PropertyName == OutputProperties.MessagePropertyName) { MessageTemplateRenderer.Render(logEvent.MessageTemplate, logEvent.Properties, writer, pt.Format, _formatProvider); } else if (pt.PropertyName == OutputProperties.TimestampPropertyName) { ScalarValue.Render(logEvent.Timestamp, writer, pt.Format, _formatProvider); } else if (pt.PropertyName == OutputProperties.PropertiesPropertyName) { PropertiesOutputFormat.Render(logEvent.MessageTemplate, logEvent.Properties, _outputTemplate, writer, pt.Format, _formatProvider); } else { // If a property is missing, don't render anything (message templates render the raw token here). if (!logEvent.Properties.TryGetValue(pt.PropertyName, out var propertyValue)) { continue; } // If the value is a scalar string, support some additional formats: 'u' for uppercase // and 'w' for lowercase. var sv = propertyValue as ScalarValue; if (sv?.Value is string literalString) { var cased = Casing.Format(literalString, pt.Format); writer.Write(cased); } else { propertyValue.Render(writer, pt.Format, _formatProvider); } } if (pt.Alignment.HasValue) { Padding.Apply(output, ((StringWriter)writer).ToString(), pt.Alignment); } } } }