public ComparisonBenchmark()
        {
            // Just the delegate invocation overhead
            _trivialFilter = evt => true;

            // `A == 3`, the old way
            _handwrittenFilter = evt =>
            {
                LogEventPropertyValue a;
                if (evt.Properties.TryGetValue("A", out a) &&
                    a is ScalarValue &&
                    ((ScalarValue)a).Value is int)
                {
                    return((int)((ScalarValue)a).Value == 3);
                }

                return(false);
            };

            // The code we're interested in; the `true.Equals()` overhead is normally added when
            // this is used with Serilog
            var compiled = FilterLanguage.CreateFilter("A = 3");

            _expressionFilter = evt => true.Equals(compiled(evt));

            Assert.True(_trivialFilter(_event) && _handwrittenFilter(_event) && _expressionFilter(_event));
        }
        public void StructuresAreExposedAsDictionaries()
        {
            var evt  = Some.InformationEvent("{@Person}", new { Name = "nblumhardt" });
            var expr = FilterLanguage.CreateFilter("Person");
            var val  = expr(evt);
            var dict = Assert.IsType <Dictionary <string, object> >(val);

            Assert.Equal("nblumhardt", dict["Name"]);
        }
예제 #3
0
        /// <summary>
        /// Exclude log events that match the provided expression.
        /// </summary>
        /// <param name="loggerFilterConfiguration">Filter configuration.</param>
        /// <param name="expression">The expression to apply.</param>
        /// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
        public static LoggerConfiguration ByExcluding(this LoggerFilterConfiguration loggerFilterConfiguration, string expression)
        {
            if (loggerFilterConfiguration == null)
            {
                throw new ArgumentNullException(nameof(loggerFilterConfiguration));
            }
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var compiled = FilterLanguage.CreateFilter(expression);

            return(loggerFilterConfiguration.ByExcluding(e => true.Equals(compiled(e))));
        }
예제 #4
0
        protected override async Task <int> Run()
        {
            try
            {
                var enrichers = new List <ILogEventEnricher>();
                foreach (var property in _properties.Properties)
                {
                    enrichers.Add(new ScalarPropertyEnricher(property.Key, property.Value));
                }

                Func <LogEvent, bool> filter = null;
                if (_filter != null)
                {
                    var expr = _filter.Replace("@Level", SurrogateLevelProperty.PropertyName);
                    var eval = FilterLanguage.CreateFilter(expr);
                    filter = evt => true.Equals(eval(evt));
                }

                using (var inputFile = _fileInputFeature.InputFilename != null
                    ? new StreamReader(File.Open(_fileInputFeature.InputFilename, FileMode.Open, FileAccess.Read,
                                                 FileShare.ReadWrite))
                    : null)
                {
                    var input = inputFile ?? Console.In;

                    var reader = _json ?
                                 (ILogEventReader) new JsonLogEventReader(input) :
                                 new PlainTextLogEventReader(input, _pattern);

                    return(await LogShipper.ShipEvents(
                               _connectionFactory.Connect(_connection),
                               reader,
                               enrichers,
                               _invalidDataHandlingFeature.InvalidDataHandling,
                               _sendFailureHandlingFeature.SendFailureHandling,
                               filter));
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Ingestion failed: {ErrorMessage}", ex.Message);
                return(1);
            }
        }
        public JsonDataExtractor(string expression)
        {
            if (expression == "@Properties")
            {
                _extract = v => v;
            }
            else
            {
                var expr = FilterLanguage.CreateFilter(expression);
                _extract = v => {
                    if (!(v is JObject obj))
                    {
                        throw new ArgumentException("Data value extraction requires a JSON object response.");
                    }

                    if (!obj.ContainsKey("@t"))
                    {
                        obj["@t"] = DateTime.UtcNow.ToString("o");
                    }

                    var le = LogEventReader.ReadFromJObject(obj);

                    var value = expr(le);
                    if (value == null)
                    {
                        return(JValue.CreateNull());
                    }

                    if (!(value is LogEventPropertyValue lepv))
                    {
                        return(JToken.FromObject(value));
                    }

                    var sw = new StringWriter();
                    ValueFormatter.Format(lepv, sw);
                    return(Serializer.Deserialize <JToken>(
                               new JsonTextReader(new StringReader(sw.ToString()))));
                };
            }
        }
        /// <summary>
        /// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
        /// </summary>
        /// <param name="loggerSinkConfiguration">Sink configuration.</param>
        /// <param name="expression">An expression that evaluates to <c>true</c> when the
        /// supplied <see cref="T:Serilog.Events.LogEvent" />
        /// should be written to the configured sink.</param>
        /// <param name="configureSink">An action that configures the wrapped sink.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
        public static LoggerConfiguration Conditional(
            this LoggerSinkConfiguration loggerSinkConfiguration,
            string expression,
            Action <LoggerSinkConfiguration> configureSink)
        {
            if (loggerSinkConfiguration == null)
            {
                throw new ArgumentNullException(nameof(loggerSinkConfiguration));
            }
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (configureSink == null)
            {
                throw new ArgumentNullException(nameof(configureSink));
            }

            var compiled = FilterLanguage.CreateFilter(expression);

            return(loggerSinkConfiguration.Conditional(e => true.Equals(compiled(e)), configureSink));
        }
        public static LoggerConfiguration UniqueOverSpan(this LoggerFilterConfiguration loggerFilterConfiguration, string expression, TimeSpan span)
        {
            if (loggerFilterConfiguration == null)
            {
                throw new ArgumentNullException(nameof(loggerFilterConfiguration));
            }

            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            var compiled = FilterLanguage.CreateFilter(expression);

            return
                (loggerFilterConfiguration
                 .UniqueOverSpan
                 (
                     e => true.Equals(compiled(e)),
                     span
                 ));
        }
예제 #8
0
        /// <summary>
        /// Write to a sink only when <paramref name="expression" /> evaluates to <c>true</c>.
        /// </summary>
        /// <param name="loggerEnrichmentConfiguration">Enrichment configuration.</param>
        /// <param name="expression">An expression that evaluates to <c>true</c> when the supplied
        /// <see cref="T:Serilog.Events.LogEvent" /> should be enriched.</param>
        /// <param name="configureEnricher">An action that configures the wrapped enricher.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <returns>The underlying <see cref="LoggerConfiguration"/>.</returns>
        public static LoggerConfiguration When(
            this LoggerEnrichmentConfiguration loggerEnrichmentConfiguration,
            string expression,
            Action <LoggerEnrichmentConfiguration> configureEnricher)
        {
            if (loggerEnrichmentConfiguration == null)
            {
                throw new ArgumentNullException(nameof(loggerEnrichmentConfiguration));
            }
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }
            if (configureEnricher == null)
            {
                throw new ArgumentNullException(nameof(configureEnricher));
            }

            var compiled = FilterLanguage.CreateFilter(expression);

            return(loggerEnrichmentConfiguration.When(e => true.Equals(compiled(e)), configureEnricher));
        }
예제 #9
0
        protected override async Task <int> Run()
        {
            try
            {
                var enrichers = new List <ILogEventEnricher>();
                foreach (var(name, value) in _properties.Properties)
                {
                    enrichers.Add(new ScalarPropertyEnricher(name, value));
                }

                if (_level != null)
                {
                    enrichers.Add(new ScalarPropertyEnricher(SurrogateLevelProperty.PropertyName, _level));
                }

                Func <LogEvent, bool> filter = null;
                if (_filter != null)
                {
                    var expr = _filter.Replace("@Level", SurrogateLevelProperty.PropertyName);
                    var eval = FilterLanguage.CreateFilter(expr);
                    filter = evt => true.Equals(eval(evt));
                }

                var connection = _connectionFactory.Connect(_connection);
                var(_, apiKey) = _connectionFactory.GetConnectionDetails(_connection);
                var batchSize = _batchSize.Value;

                foreach (var input in _fileInputFeature.OpenInputs())
                {
                    using (input)
                    {
                        var reader = _json
                            ? (ILogEventReader) new JsonLogEventReader(input)
                            : new PlainTextLogEventReader(input, _pattern);

                        reader = new EnrichingReader(reader, enrichers);

                        if (_message != null)
                        {
                            reader = new StaticMessageTemplateReader(reader, _message);
                        }

                        var exit = await LogShipper.ShipEvents(
                            connection,
                            apiKey,
                            reader,
                            _invalidDataHandlingFeature.InvalidDataHandling,
                            _sendFailureHandlingFeature.SendFailureHandling,
                            batchSize,
                            filter);

                        if (exit != 0)
                        {
                            return(exit);
                        }
                    }
                }

                return(0);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Ingestion failed: {ErrorMessage}", ex.Message);
                return(1);
            }
        }