Ejemplo n.º 1
0
        private void GetEventInfoFromAttribute(CustomEventRequest customEvent)
        {
            // walk up the stack and check for our EventGridSinkAttribute
            var st          = new StackTrace();
            var stackFrames = st.GetFrames();

            if (stackFrames == null)
            {
                return;
            }

            var methods = stackFrames.Where(f => f != null).Select(f => f.GetMethod()).ToArray();
            // walk through serilog to reach the calling method
            var callingMethod = methods.FirstOrDefault(m => !m?.DeclaringType?.FullName?.StartsWith("Serilog") ?? false) ?? methods.First();

            var subjectAttributeValue = GetCustomValueFromAttribute <EventGridSubjectAttribute>(methods);
            var typeAttributeValue    = GetCustomValueFromAttribute <EventGridTypeAttribute>(methods);

            // assign the event info, failing back to generic defaults
            customEvent.Subject   = customEvent.Subject ?? subjectAttributeValue ?? GetSubject();
            customEvent.EventType = customEvent.EventType ?? typeAttributeValue ?? _customEventType ?? GetEventType() ?? "AppDomain/Class";

            string GetSubject()
            {
                var methodName = GetMethodWithParams() ?? "Method/default";

                return($"{methodName}");
            }

            string GetMethodWithParams()
            {
                var parameterNames = callingMethod != null && callingMethod.GetParameters().Any()
          ? callingMethod.GetParameters().Select(x => x.Name).Aggregate((combined, next) => combined += string.IsNullOrEmpty(combined) ? next : $"/{next}")
          : "default";
                var methodWithParameters = $"{callingMethod?.Name}/{parameterNames}";

                return(methodWithParameters);
            }

            string GetEventType()
            {
                var assemblyName = callingMethod?.ReflectedType?.Assembly.GetName().Name ?? "General";
                var className    = callingMethod?.ReflectedType?.Name ?? "Class";

                return($"{assemblyName}/{className}");
            }
        }
Ejemplo n.º 2
0
        public async Task SendEvent(LogEvent logEvent)
        {
            // make a dictionary from the log event properties
            var props = logEvent.Properties
                        .Select(pv => new { Name = pv.Key, Value = EventGridPropertyFormatter.Simplify(pv.Value) })
                        .ToDictionary(a => a.Name, b => b.Value);

            // build the request from sink config and log event properties
            var customEvent = new CustomEventRequest
            {
                Subject   = _customEventSubject ?? GetEventSubjectFromProperties(props),
                EventType = _customEventType ?? GetEventTypeFromProperties(props)
            };

            // if we don't have what we need from the config or the event, pull event info from the call stack
            if (string.IsNullOrEmpty(customEvent.Subject) || string.IsNullOrEmpty(customEvent.EventType))
            {
                GetEventInfoFromAttribute(customEvent);
            }

            // add log severity information
            props.Add("Severity", logEvent.Level.ToString());

            // clean up the payload
            props.Add("LogMessage", logEvent.MessageTemplate.Render(logEvent.Properties));
            customEvent.Data = props.Where(p => p.Key != _customSubjectPropertyName && p.Key != _customTypePropertyName);

            // finally, we have what we need post the event
            var client  = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, _topicUri);

            request.Headers.Add(_customEventRequestAuth == CustomEventRequestAuth.Key ? "aeg-sas-key" : "aeg-sas-token", _key);
            var body = new[] { customEvent };

            var json = JsonConvert.SerializeObject(body, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore,
                ContractResolver  = new CamelCasePropertyNamesContractResolver()
            });

            request.Content = new StringContent(json);
            await client.SendAsync(request);
        }