/// <summary> /// Emit the provided log event to the sink. /// </summary> /// <param name="logEvent">The log event to write.</param> public void Emit(LogEvent logEvent) { //Include the log level as a tag. var tags = _tags.Concat(new [] { logEvent.Level.ToString() }).ToList(); var properties = logEvent.Properties .Select(pv => new { Name = pv.Key, Value = RaygunPropertyFormatter.Simplify(pv.Value) }) .ToDictionary(a => a.Name, b => b.Value); // Add the message properties.Add("RenderedLogMessage", logEvent.RenderMessage(_formatProvider)); properties.Add("LogMessageTemplate", logEvent.MessageTemplate.Text); // Create new message var raygunMessage = new RaygunMessage { OccurredOn = logEvent.Timestamp.UtcDateTime }; // Add exception when available if (logEvent.Exception != null) { raygunMessage.Details.Error = RaygunErrorMessageBuilder.Build(logEvent.Exception); } // Add user when requested if (!String.IsNullOrWhiteSpace(_userNameProperty) && logEvent.Properties.ContainsKey(_userNameProperty) && logEvent.Properties[_userNameProperty] != null) { raygunMessage.Details.User = new RaygunIdentifierMessage(logEvent.Properties[_userNameProperty].ToString()); } // Add version when requested if (!String.IsNullOrWhiteSpace(_applicationVersionProperty) && logEvent.Properties.ContainsKey(_applicationVersionProperty) && logEvent.Properties[_applicationVersionProperty] != null) { raygunMessage.Details.Version = logEvent.Properties[_applicationVersionProperty].ToString(); } // Build up the rest of the message raygunMessage.Details.Environment = new RaygunEnvironmentMessage(); raygunMessage.Details.Tags = tags; raygunMessage.Details.UserCustomData = properties; raygunMessage.Details.MachineName = Environment.MachineName; if (HttpContext.Current != null) { // Request message is built here instead of raygunClient.Send so RequestMessageOptions have to be constructed here var requestMessageOptions = new RaygunRequestMessageOptions(_ignoredFormFieldNames, Enumerable.Empty <string>(), Enumerable.Empty <string>(), Enumerable.Empty <string>()); raygunMessage.Details.Request = RaygunRequestMessageBuilder.Build(HttpContext.Current.Request, requestMessageOptions); } // Submit //_client.SendInBackground(raygunMessage); _client.Send(raygunMessage); }
/// <summary> /// Emit the provided log event to the sink. /// </summary> /// <param name="logEvent">The log event to write.</param> public void Emit(LogEvent logEvent) { var tags = new List <String> { logEvent.Level.ToString() }; var properties = logEvent.Properties .Select(pv => new { Name = pv.Key, Value = RaygunPropertyFormatter.Simplify(pv.Value) }) .ToDictionary(a => a.Name, b => b.Value); // Add the message properties.Add("Message", logEvent.RenderMessage(_formatProvider)); properties.Add("MessageTemplate", logEvent.MessageTemplate.Text); // Create new message var raygunMessage = new RaygunMessage { OccurredOn = logEvent.Timestamp.UtcDateTime }; // Add exception when available if (logEvent.Exception != null) { raygunMessage.Details.Error = new RaygunErrorMessage(logEvent.Exception); } // Add user when requested if (!String.IsNullOrWhiteSpace(_userNameProperty) && logEvent.Properties.ContainsKey(_userNameProperty) && logEvent.Properties[_userNameProperty] != null) { raygunMessage.Details.User = new RaygunIdentifierMessage(logEvent.Properties[_userNameProperty].ToString()); } // Add version when requested if (!String.IsNullOrWhiteSpace(_applicationVersionProperty) && logEvent.Properties.ContainsKey(_applicationVersionProperty) && logEvent.Properties[_applicationVersionProperty] != null) { raygunMessage.Details.Version = logEvent.Properties[_applicationVersionProperty].ToString(); } // Build up the rest of the message raygunMessage.Details.Environment = new RaygunEnvironmentMessage(); raygunMessage.Details.Tags = tags; raygunMessage.Details.UserCustomData = properties; raygunMessage.Details.MachineName = Environment.MachineName; if (HttpContext.Current != null) { raygunMessage.Details.Request = new RaygunRequestMessage(HttpContext.Current.Request, null); } // Submit _client.SendInBackground(raygunMessage); }
/// <summary> /// Emit the provided log event to the sink. /// </summary> /// <param name="logEvent">The log event to write.</param> public void Emit(LogEvent logEvent) { //Include the log level as a tag. var tags = _tags.Concat(new[] { logEvent.Level.ToString() }).ToList(); var properties = logEvent.Properties .Select(pv => new { Name = pv.Key, Value = RaygunPropertyFormatter.Simplify(pv.Value) }) .ToDictionary(a => a.Name, b => b.Value); // Add the message properties.Add("RenderedLogMessage", logEvent.RenderMessage(_formatProvider)); properties.Add("LogMessageTemplate", logEvent.MessageTemplate.Text); // Create new message var raygunMessage = new RaygunMessage { OccurredOn = logEvent.Timestamp.UtcDateTime }; // Add exception when available, else use the message template so events can be grouped raygunMessage.Details.Error = logEvent.Exception != null ? RaygunErrorMessageBuilder.Build(logEvent.Exception) : new RaygunErrorMessage() { ClassName = logEvent.MessageTemplate.Text, Message = logEvent.MessageTemplate.Text, Data = logEvent.Properties.ToDictionary(k => k.Key, v => v.Value.ToString()) }; // Add user when requested if (!string.IsNullOrWhiteSpace(_userNameProperty) && logEvent.Properties.ContainsKey(_userNameProperty) && logEvent.Properties[_userNameProperty] != null) { raygunMessage.Details.User = new RaygunIdentifierMessage(logEvent.Properties[_userNameProperty].ToString()); } // Add version when requested if (!String.IsNullOrWhiteSpace(_applicationVersionProperty) && logEvent.Properties.ContainsKey(_applicationVersionProperty) && logEvent.Properties[_applicationVersionProperty] != null) { raygunMessage.Details.Version = logEvent.Properties[_applicationVersionProperty].ToString("l", null); } // Build up the rest of the message raygunMessage.Details.Environment = new RaygunEnvironmentMessage(); raygunMessage.Details.Tags = tags; raygunMessage.Details.UserCustomData = properties; raygunMessage.Details.MachineName = Environment.MachineName; // Add the custom group key when provided if (properties.TryGetValue(_groupKeyProperty, out var customKey)) { raygunMessage.Details.GroupingKey = customKey.ToString(); } // Add additional custom tags if (properties.TryGetValue(_tagsProperty, out var eventTags) && eventTags is object[]) { foreach (var tag in (object[])eventTags) { raygunMessage.Details.Tags.Add(tag.ToString()); } } // Submit _client.SendInBackground(raygunMessage); }
private void OnCustomGroupingKey(object sender, RaygunCustomGroupingKeyEventArgs e) { if (e?.Message?.Details != null) { var details = e.Message.Details; details.Client = new RaygunClientMessage { Name = "RaygunSerilogSink", Version = new AssemblyName(this.GetType().Assembly.FullName).Version.ToString(), ClientUrl = "https://github.com/serilog/serilog-sinks-raygun" }; if (details.UserCustomData is Dictionary <string, LogEventPropertyValue> properties) { // If an Exception has not been provided, then use the log message/template to fill in the details and attach the current execution stack if (e.Exception is NullException nullException) { details.Error = new RaygunErrorMessage { ClassName = properties[LogMessageTemplateProperty].AsString(), Message = properties[RenderedLogMessageProperty].AsString(), StackTrace = RaygunErrorMessageBuilder.BuildStackTrace(nullException.CodeExecutionStackTrace) }; } if (properties.TryGetValue(OccurredProperty, out var occurredOnPropertyValue) && occurredOnPropertyValue is ScalarValue occurredOnScalar && occurredOnScalar.Value is DateTime occurredOn) { e.Message.OccurredOn = occurredOn; properties.Remove(OccurredProperty); } // Add user information if provided if (!string.IsNullOrWhiteSpace(_userInfoProperty) && properties.TryGetValue(_userInfoProperty, out var userInfoPropertyValue) && userInfoPropertyValue != null) { switch (userInfoPropertyValue) { case StructureValue userInfoStructure: details.User = BuildUserInformationFromStructureValue(userInfoStructure); break; case ScalarValue userInfoScalar when userInfoScalar.Value is string userInfo: details.User = ParseUserInformation(userInfo); break; } if (details.User != null) { details.UserCustomData.Remove(_userInfoProperty); } } // If user information is not set, then use the user-name if provided if (details.User == null && !string.IsNullOrWhiteSpace(_userNameProperty) && properties.ContainsKey(_userNameProperty) && properties[_userNameProperty] != null) { details.User = new RaygunIdentifierMessage(properties[_userNameProperty].AsString()); properties.Remove(_userNameProperty); } // Add version if provided if (!string.IsNullOrWhiteSpace(_applicationVersionProperty) && properties.ContainsKey(_applicationVersionProperty) && properties[_applicationVersionProperty] != null) { details.Version = properties[_applicationVersionProperty].AsString(); properties.Remove(_applicationVersionProperty); } // Add the custom group key if provided if (properties.TryGetValue(_groupKeyProperty, out var customKey)) { details.GroupingKey = customKey.AsString(); properties.Remove(_groupKeyProperty); } #if NETSTANDARD2_0 // Add Http request/response messages if present and not already set if (details.Request == null && properties.TryGetValue(RaygunClientHttpEnricher.RaygunRequestMessagePropertyName, out var requestMessageProperty) && requestMessageProperty is StructureValue requestMessageValue) { details.Request = BuildRequestMessageFromStructureValue(requestMessageValue); properties.Remove(RaygunClientHttpEnricher.RaygunRequestMessagePropertyName); } if (details.Response == null && properties.TryGetValue(RaygunClientHttpEnricher.RaygunResponseMessagePropertyName, out var responseMessageProperty) && responseMessageProperty is StructureValue responseMessageValue) { details.Response = BuildResponseMessageFromStructureValue(responseMessageValue); properties.Remove(RaygunClientHttpEnricher.RaygunResponseMessagePropertyName); } #endif // Simplify the remaining properties to be used as user-custom-data details.UserCustomData = properties .Select(pv => new { Name = pv.Key, Value = RaygunPropertyFormatter.Simplify(pv.Value) }) .ToDictionary(a => a.Name, b => b.Value); } } }