private void PostLoggingEvent(LoggingEvent[] loggingEvents) { var formatter = new LokiBatchFormatter(labels); var httpClient = new LokiHttpClient(TrustSelfCignedCerts); if (httpClient is LokiHttpClient c) { LokiCredentials credentials; if (!string.IsNullOrEmpty(BasicAuthUserName) && !string.IsNullOrEmpty(BasicAuthPassword)) { credentials = new BasicAuthCredentials(ServiceUrl, BasicAuthUserName, BasicAuthPassword); } else { credentials = new NoAuthCredentials(ServiceUrl); } c.SetAuthCredentials(credentials); } using (MemoryStream ms = new MemoryStream()) using (var sc = new StreamWriter(ms)) { formatter.Format(loggingEvents, sc); sc.Flush(); ms.Position = 0; var content = new StreamContent(ms); var contentStr = content.ReadAsStringAsync().Result; // TO VERIFY httpClient.PostAsync(LokiRouteBuilder.BuildPostUri(ServiceUrl), content); } }
public LokiBatchFormatterBenchmark() { this.textWriter = new StreamWriter(Stream.Null); var labelValues = Enumerable.Range(0, LABEL_CARDINALITY).Select(i => Guid.NewGuid().ToString()).ToArray(); var random = new Random(); var propertyNames = Enumerable.Range(0, LOG_PROPERTY_COUNT) .Select(index => Guid.NewGuid().ToString()); this.LabelNames = propertyNames.Take(LOG_LABEL_COUNT); this.logEvents = Enumerable.Range(0, LOG_EVENT_COUNT).Select(index => { return(new LogEvent( new DateTimeOffset(index, TimeSpan.Zero), LogEventLevel.Debug, null, new MessageTemplate(Guid.NewGuid().ToString(), new List <MessageTemplateToken>()), propertyNames.Select(name => new LogEventProperty(name, new ScalarValue(labelValues[random.Next(0, LABEL_CARDINALITY - 1)]))).ToList())); }).ToList(); this.lokiBatchFormatter = new LokiBatchFormatter(null, this.LabelNames, false); }
/// <summary> /// Adds a non-durable sink that will send log events to Grafana Loki. /// A non-durable sink will lose data after a system or process restart. /// </summary> /// <param name="sinkConfiguration"> /// The logger configuration. /// </param> /// <param name="uri"> /// The root URI of Loki. /// </param> /// <param name="labels"> /// The global log event labels, which will be user for enriching all requests. /// </param> /// <param name="propertiesAsLabels"> /// The list of properties, which would be mapped to the labels. /// </param> /// <param name="credentials"> /// Auth <see cref="LokiCredentials"/>. /// </param> /// <param name="restrictedToMinimumLevel"> /// The minimum level for events passed through the sink. /// Default value is <see cref="LevelAlias.Minimum"/>. /// </param> /// <param name="batchPostingLimit"> /// The maximum number of events to post in a single batch. Default value is 1000. /// </param> /// <param name="queueLimit"> /// The maximum number of events stored in the queue in memory, waiting to be posted over /// the network. Default value is infinitely. /// </param> /// <param name="period"> /// The time to wait between checking for event batches. Default value is 2 seconds. /// </param> /// <param name="textFormatter"> /// The formatter rendering individual log events into text, for example JSON. Default /// value is <see cref="MessageTemplateTextFormatter"/>. /// </param> /// <param name="httpClient"> /// A custom <see cref="ILokiHttpClient"/> implementation. Default value is /// <see cref="LokiHttpClient"/>. /// </param> /// <param name="reservedPropertyRenamingStrategy"> /// Renaming strategy for properties' names equal to reserved keywords. /// </param> /// <param name="useInternalTimestamp"> /// Should use internal sink timestamp instead of application one to use as log timestamp. /// </param> /// <returns>Logger configuration, allowing configuration to continue.</returns> public static LoggerConfiguration GrafanaLoki( this LoggerSinkConfiguration sinkConfiguration, string uri, IEnumerable <LokiLabel>?labels = null, IEnumerable <string>?propertiesAsLabels = null, LokiCredentials?credentials = null, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, int batchPostingLimit = 1000, int?queueLimit = null, TimeSpan?period = null, ITextFormatter?textFormatter = null, ILokiHttpClient?httpClient = null, IReservedPropertyRenamingStrategy?reservedPropertyRenamingStrategy = null, bool useInternalTimestamp = false) { if (sinkConfiguration == null) { throw new ArgumentNullException(nameof(sinkConfiguration)); } reservedPropertyRenamingStrategy ??= new DefaultReservedPropertyRenamingStrategy(); period ??= TimeSpan.FromSeconds(1); textFormatter ??= new LokiJsonTextFormatter(reservedPropertyRenamingStrategy); httpClient ??= new LokiHttpClient(); httpClient.SetCredentials(credentials); var batchFormatter = new LokiBatchFormatter( reservedPropertyRenamingStrategy, labels, propertiesAsLabels, useInternalTimestamp); var sink = new LokiSink( LokiRoutesBuilder.BuildLogsEntriesRoute(uri), batchPostingLimit, queueLimit, period.Value, textFormatter, batchFormatter, httpClient); return(sinkConfiguration.Sink(sink, restrictedToMinimumLevel)); }