public override bool Evaluate(IDiagnosticEvent diagnosticEvent, ILoggerName loggerName)
        {
            bool meetsCriteria = true;

            if (!Evaluator.Value.MatchesPattern(diagnosticEvent.LoggerName))
            {
                meetsCriteria = false;
            }
            else
            {
                foreach (var name in loggerName.NamePartHierarchy)
                {
                    if (!Evaluator.Value.MatchesPattern(name))
                    {
                        meetsCriteria = false;
                        break;
                    }
                }
            }

            if (Mode == FilterMode.Include)
                return meetsCriteria;
            else
                return !meetsCriteria;
        }
        /// <summary>
        /// Processes specified Diagnostic Event.
        /// Attaches context information, applies filters and sends to Sinks.
        /// </summary>
        /// <param name="de"></param>
        public virtual void ProcessDiagnosticEvent(IDiagnosticEvent de)
        {
            // if logging disabled, exit early to improve performance
            if (!Config.Settings.EnableLogging)
                return;

            // make a copy of reference to current configuration
            // to make sure that any changes (which would replace Config)
            // will not be applied to this method before it exits
            var config_ref = Config;

            ProcessDiagnosticEventInternal(de, config_ref);
        }
예제 #3
0
        public override void Write(IDiagnosticEvent de)
        {
            var text = Formatter.Format(de);

            if (BeforeWrite != null)
            {
                // todo: this may need to support different encoding types)
                var args = new BeforeWriteEventArgs(text.Length);

                BeforeWrite(this, args);
            }

            using (var lockToken = FileLockingStrategy.AcquireLock(LogFile.FullName))
            {
                lockToken.Write(text);
            }
        }
예제 #4
0
        public override bool Evaluate(IDiagnosticEvent diagnosticEvent, ILoggerName loggerName)
        {
            bool meetsCriteria = false;

            var propertyValue = (object) null;

            if (!diagnosticEvent.Properties.TryGetValue(Property, out propertyValue))
            {
                InternalTrace.Warning(() =>
                    "Diagnostic Property '{0}' not found on Diagnostic Event."
                    .FormatWith(Property));

                meetsCriteria = false;
            }
            else
            {
                meetsCriteria = Evaluator.Value.MatchesPattern(propertyValue.ToString());
            }

            if (Mode == FilterMode.Include)
                return meetsCriteria;
            else
                return !meetsCriteria;
        }
        void ProcessDiagnosticEventInternal(IDiagnosticEvent de, DiagnosticsConfiguration config_ref)
        {
            // NOTE:    This method is *performance critical* and should be optimized for quickest execution even at cost of readability

            try
            {
                if (!config_ref.Settings.EnableLogging)
                    return;

                //# Include Caller Info
                if (config_ref.Settings.IncludeCallerInfo || config_ref.Settings.UseCallerNameAsLoggerName)
                {
                    de.IncludeCallerInformation(
                        config_ref.Settings.UseCallerNameAsLoggerName,
                        config_ref.Settings.IncludeCallerInfo);
                }

                //# Override logger name only if it has not already been set (custom name might have been used)
                if (de.LoggerName == null)
                    de.LoggerName = Name.ToString();

                //# COPY GLOBAL PROPERTIES
                de.Properties.AddOrUpdateRange(GlobalProperties);

                //# EVALUATE AND PIN DIAGNOSTIC EVENT DATA
                de.EvaluateAndPinAllDataIfNeeded();

                //# GLOBAL FILTER
                
                //! Filtering on a global level must happen *after* logger name is set and properties pinned
                //! This is because filters are most likely use their values

                if (!MeetsFiltersCriteria(de, Name, config_ref.GlobalFilters))
                    return;

                //# GET SINKS

                // only use sinks which meet filtering criteria for this event

                var mustWaitForWriteSinks =
                    (from s in config_ref.Sinks.MustWaitForWriteSinks
                     where s.Filter.Evaluate(de, Name)
                     select s).ToArray();

                var fireAndForgetSinks =
                    (from s in config_ref.Sinks.FireAndForgetSinks
                     where s.Filter.Evaluate(de, Name)
                     select s).ToArray();

                var allSinks = mustWaitForWriteSinks.Concat(fireAndForgetSinks).ToArray();

                //# REQUESTED CONTEXT DATA

                // get requested context data (requested by sinks via formatters)

                var isAdditionalContextDataRequested = false;

                var allRequestedContextData = new List<IDataRequest>(capacity: 27);

                for(int sink_ix = 0; sink_ix < allSinks.Length; sink_ix++)
                {
                    var sink = allSinks[sink_ix];

                    var requestedContextData = sink.GetRequestedContextData();

                    for(int cd_ix = 0; cd_ix < requestedContextData.Count; cd_ix++)
                    {
                        var cd = requestedContextData[cd_ix];

                        allRequestedContextData.Add(cd);

                        if (cd.Data == "Event.AdditionalContextData")
                            isAdditionalContextDataRequested = true;
                    }
                }

                allRequestedContextData = allRequestedContextData.Distinct().ToList(); // todo: check if performance of distinct is good enough
                
                //# INCLUDE DATA REQUESTED BY SINKS

                var requestedData = config_ref.ContextDataCollectors.Collect(allRequestedContextData);
                de.Properties.AddOrUpdateRange(requestedData);

                //# GET ADDITIONAL CONTEXT INFORMATION

                if (isAdditionalContextDataRequested)
                {
                    var additionalContextdataCollectors = config_ref.AdditionalContextDataCollectors;

                    for (int i = 0; i < additionalContextdataCollectors.Count; i++)
                    {
                        var collector = additionalContextdataCollectors[i];

                        // if collector has no filter then it should be used.
                        if (collector.Filter == null)
                        {
                            de.AdditionalContextData.AddOrUpdateRange(collector.CollectData());
                            de.PinAdditionalContextDataIfNeeded();
                            break;
                        }

                        if (collector.Filter.Evaluate(de, this.Name))
                        {
                            de.AdditionalContextData.AddOrUpdateRange(collector.CollectData());
                            de.PinAdditionalContextDataIfNeeded();
                            break;
                        }
                    }
                }

                //# WRITE TO SINKS

                if (mustWaitForWriteSinks.Length > 0)
                {
                    if (mustWaitForWriteSinks.Length == 1)
                    {
                        var sink = mustWaitForWriteSinks.Single();

                        sink.Write(de);
                    }
                    else
                    {
                        ParallelExtensions.ForEach(mustWaitForWriteSinks, (sink) =>
                        {
                            sink.Write(de);
                        });
                    }
                }

                // then write to all fire-and-forget sinks

                if (fireAndForgetSinks.Length > 0)
                    ParallelExtensions.ForEachNoWait(
                        fireAndForgetSinks,
                        (sink) =>
                        {
                            if (sink.Filter.Evaluate(de, Name))
                                sink.Write(de);
                        });
            }
            catch (Exception ex)
            {
                InternalTrace.Error(ex, "Failed to log diagnostic event.");
            }
        }
        /// <summary>
        /// Checks if specified Diagnostic Event meets filtering criteria.
        /// </summary>
        /// <param name="de"></param>
        /// <param name="loggerName"></param>
        /// <param name="filters"></param>
        /// <returns></returns>
        internal bool MeetsFiltersCriteria(IDiagnosticEvent de, ILoggerName loggerName, IFilterCollection filters)
        {
            //# check this loger's filters
            for (int i = 0; i < filters.Count; i++)
            {
                var filter = filters[i];

                bool shouldLog = filter.Evaluate(de, loggerName);

                if (!shouldLog)
                    return false;
            }

            var parentLogger = Parent as DiagnosticLogger;

            if (parentLogger != null)
                return parentLogger.MeetsFiltersCriteria(de, loggerName, filters);

            return true;
        }
예제 #7
0
        public override void Write(IDiagnosticEvent de)
        {
            //if (Bundle != null)
            //{
            //    if (Bundle.TryBundle(de))
            //    {
            //        // event added to the bundle
            //        // do nothing else
            //        return;
            //    }
            //    else
            //    {
            //        // event not added to bundle,
            //        // proceed as usual
            //    }
            //}

            // TODO: allow to specify smtp config in diag config rather than always using one from app.config

            // TODO: this is just a quick mockup to get it working for demo, must be rewriten properly

            PatternFormatter f = new PatternFormatter();

            var msg = new MailMessage();

            var toElements = To.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < toElements.Length; i++)
            {
                f = new PatternFormatter();
                f.Pattern = toElements[i];

                var toformatted = f.Format(de);
                msg.To.Add(toformatted);
            }

            msg.From = new MailAddress(From);

            msg.Subject = Subject.Format(de);

            msg.Body = Body.Format(de);

            if (!LogsToAttach.IsNullOrEmpty())
            {
                // todo: support multiple logs

                throw new NotImplementedException();

                //var config_ref = GlobalDiagnostics.GlobalLogger.Config;

                //var sink =
                //    (from s in config_ref.SinkDefinitions
                //     where s is FileSink
                //     && s.Name == LogsToAttach
                //     select s as FileSink).FirstOrDefault();


                //var attachmentStream = new MemoryStream();

                //using (var l = sink.FileLockingStrategy.AcquireLock(sink.LogFile.FullName))
                //{
                //    using (var fs = new FileStream(sink.SinkLocation.Location, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                //    {
                //        using (var gz = new GZipStream(attachmentStream, CompressionMode.Compress, leaveOpen: true))
                //        {
                //            fs.CopyTo(gz);
                //        }
                //    }
                //}

                //if (attachmentStream != null)
                //{
                //    attachmentStream.Seek(0, SeekOrigin.Begin);

                //    var attachment = new Attachment(attachmentStream, sink.LogFile.Name + ".gz");
                //    msg.Attachments.Add(attachment);
                //}
            }


            SmtpClient.Send(msg);
        }
예제 #8
0
 public abstract void Write(IDiagnosticEvent de);
예제 #9
0
 public abstract bool Evaluate(IDiagnosticEvent diagnosticEvent, ILoggerName loggerName);
예제 #10
0
 public override bool Evaluate(IDiagnosticEvent diagnosticEvent, ILoggerName loggerName)
 {
     return true;
 }
예제 #11
0
 public string Format(IDiagnosticEvent de)
 {
     return de.Message;
 }
예제 #12
0
        public override void Write(IDiagnosticEvent de)
        {
            var msg = Formatter.Format(de);

            Trace.Write(msg);
        }
예제 #13
0
 public override void Write(IDiagnosticEvent de)
 {
     Events.Add(de);
 }
예제 #14
0
 public void ProcessDiagnosticEvent(IDiagnosticEvent de)
 {
     throw new NotImplementedException();
 }
예제 #15
0
 public override bool Evaluate(IDiagnosticEvent diagnosticEvent, ILoggerName loggerName)
 {
     return EvaluateInternal(diagnosticEvent.Severity);
 }
예제 #16
0
        public string Format(IDiagnosticEvent de)
        {
            var context = new TextTemplateProcessingContext();

            foreach (var property in de.Properties)
            {
                var prop = property;

                context.Substitutions.AddOrUpdateSubstitution(
                    property.UniqueName,
                    (cx) =>
                    {
                        return prop.Value;
                    });
            }

            var txt = TextTemplateProcessingServce.ProcessTemplate(Template, context);

            return txt.ExpandTabs();
        }