using System; using System.Collections.Generic; using NLog.Common; using NLog.Layouts; using NLog.Targets.OpenTelemetryProtocol.Exceptions; using OpenTelemetry; using OpenTelemetry.Exporter; using OpenTelemetry.Logs; using OpenTelemetry.Resources; using static System.String; namespace NLog.Targets.OpenTelemetryProtocol { [Target("OtlpTarget")] public class OtlpTarget : TargetWithLayout { private OpenTelemetry.Logs.Logger _logger; private BatchLogRecordExportProcessor _processor; public bool UseHttp { get; set; } = false; public string Endpoint { get; set; } = "http://localhost:4317"; public Layout Resources { get; set; } public string ServiceName { get; set; } protected override void InitializeTarget() { _processor = CreateProcessor(); var resourceBuilder = CreateResourceBuilder(); _logger = Sdk .CreateLoggerProviderBuilder() .SetResourceBuilder(resourceBuilder) .AddProcessor(new EnrichingProcessor()) .AddProcessor(_processor) .Build() .GetLogger(); base.InitializeTarget(); } private BatchLogRecordExportProcessor CreateProcessor() { try { var options = new OtlpExporterOptions(); options.Endpoint = new Uri(Endpoint); options.Protocol = UseHttp ? OtlpExportProtocol.HttpProtobuf : OtlpExportProtocol.Grpc; var otlpLogExporterType = Type.GetType( "OpenTelemetry.Exporter.OtlpLogExporter, OpenTelemetry.Exporter.OpenTelemetryProtocol, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7bd6737fe5b67e3c"); var ctor = otlpLogExporterType.GetConstructor(new[] { typeof(OtlpExporterOptions) }); BaseExporter otlpExporter = (BaseExporter)ctor.Invoke(new[] { options }); return new BatchLogRecordExportProcessor( otlpExporter); } catch (Exception ex) { InternalLogger.Error(ex, "OtlpTarget(Name={0}) - An exception occured when creating an export processor.", Name); throw new FailedToCreateProcessorException("Failed to create an export processor"); } } private ResourceBuilder CreateResourceBuilder() { var resourceBuilder = ResourceBuilder.CreateEmpty(); if (Resources != null) { var resources = RenderLogEvent(Resources, LogEventInfo.CreateNullEvent()).Split(';'); var attributes = new List>(); foreach (var resource in resources) { var kvp = resource.Split('='); attributes.Add(new KeyValuePair(kvp[0], kvp[1])); } resourceBuilder.AddAttributes(attributes); } if (!IsNullOrEmpty(ServiceName)) { resourceBuilder.AddService(ServiceName); } return resourceBuilder; } protected override void Write(LogEventInfo logEvent) { var data = new LogRecordData { Body = logEvent.Message, SeverityText = logEvent.Level.ToString(), Timestamp = logEvent.TimeStamp }; _logger.EmitLog(data); } protected override void CloseTarget() { _processor.ForceFlush(); base.CloseTarget();; } } }