예제 #1
0
 static IEnumerable <LogEventProperty> GetProperties(object value, ILogEventPropertyValueFactory recursive)
 {
     foreach (var prop in value.GetType().GetPropertiesRecursive())
     {
         object propValue;
         try
         {
             propValue = prop.GetValue(value);
         }
         catch (TargetParameterCountException)
         {
             SelfLog.WriteLine("The property accessor {0} is a non-default indexer", prop);
             continue;
         }
         catch (TargetInvocationException ex)
         {
             SelfLog.WriteLine("The property accessor {0} threw exception {1}", prop, ex);
             propValue = "The property accessor threw an exception: " + ex.InnerException.GetType().Name;
         }
         yield return(new LogEventProperty(prop.Name, recursive.CreatePropertyValue(propValue, true)));
     }
 }
예제 #2
0
 private void RollDatabase()
 {
     try
     {
         using (var dnConn = GetSqLiteConnection())
         {
             if (new FileInfo(_databasePath).Length > _maxDatabaseSize * 1024 * 1024)
             {
                 var dbExtension = Path.GetExtension(_databasePath);
                 var newFilePath = Path.Combine(Path.GetDirectoryName(_databasePath) ?? "Logs",
                                                $"{Path.GetFileNameWithoutExtension(_databasePath)}-{DateTime.Now:yyyyMMdd_hhmmss.ff}{dbExtension}");
                 File.Copy(_databasePath, newFilePath, true);
                 dnConn.DeleteAll <Logs>();
                 SelfLog.WriteLine($"Rolling database to {newFilePath}");
             }
         }
     }
     catch (Exception e)
     {
         SelfLog.WriteLine(e.Message);
     }
 }
        protected override void EmitBatch(IEnumerable <LogEvent> events)
        {
            // ReSharper disable once PossibleMultipleEnumeration
            try
            {
                Task[] sendTasks = events.Select(logEvent =>
                {
                    JObject json    = _converter.Value.GetGelfJson(logEvent);
                    Task resultTask = _transport.Value.Send(json.ToString(Newtonsoft.Json.Formatting.None));
                    return(resultTask);
                }).ToArray();

                var t = Task.WhenAll(sendTasks);
                t.GetAwaiter().GetResult();
                base.EmitBatch(events);
            }
            catch (Exception exc)
            {
                SelfLog.WriteLine("Oops something going wrong {0}", exc);
            }
            // ReSharper disable once PossibleMultipleEnumeration
        }
예제 #4
0
        void ApplyRetentionPolicy(string currentFilePath)
        {
            if (_retainedFileCountLimit == null)
            {
                return;
            }

            var currentFileName = Path.GetFileName(currentFilePath);

            // We consider the current file to exist, even if nothing's been written yet,
            // because files are only opened on response to an event being processed.
            var potentialMatches = Directory.GetFiles(_roller.LogFileDirectory, _roller.DirectorySearchPattern)
                                   .Select(Path.GetFileName)
                                   .Union(new [] { currentFileName });

            var newestFirst = _roller
                              .SelectMatches(potentialMatches)
                              .OrderByDescending(m => m.DateTime)
                              .ThenByDescending(m => m.SequenceNumber)
                              .Select(m => m.Filename);

            var toRemove = newestFirst
                           .Where(n => StringComparer.OrdinalIgnoreCase.Compare(currentFileName, n) != 0)
                           .Skip(_retainedFileCountLimit.Value - 1)
                           .ToList();

            foreach (var obsolete in toRemove)
            {
                var fullPath = Path.Combine(_roller.LogFileDirectory, obsolete);
                try
                {
                    System.IO.File.Delete(fullPath);
                }
                catch (Exception ex)
                {
                    SelfLog.WriteLine("Error {0} while removing obsolete file {1}", ex, fullPath);
                }
            }
        }
        public async Task <SentPayloadResult> SendPayloadAsync(List <string> payload, bool first)
        {
            try
            {
                if (payload == null || !payload.Any())
                {
                    return(new SentPayloadResult(null, true));
                }
                var response = await _elasticLowLevelClient.BulkAsync <DynamicResponse>(PostData.MultiJson(payload));

                if (response.Success)
                {
                    var cleanPayload   = new List <string>();
                    var invalidPayload = GetInvalidPayloadAsync(response, payload, out cleanPayload);
                    if ((cleanPayload?.Any() ?? false) && first)
                    {
                        await SendPayloadAsync(cleanPayload, false);
                    }

                    return(new SentPayloadResult(response, true, invalidPayload));
                }
                else
                {
                    SelfLog.WriteLine("Received failed ElasticSearch shipping result {0}: {1}", response.HttpStatusCode,
                                      response.OriginalException);
                    return(new SentPayloadResult(response, false,
                                                 new InvalidResult()
                    {
                        StatusCode = response.HttpStatusCode ?? 500,
                        Content = response.OriginalException.ToString()
                    }));
                }
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex);
                return(new SentPayloadResult(null, false, null, ex));
            }
        }
        private void CreateDynamoDbLogTable()
        {
            var request = new CreateTableRequest(
                tableName: tableName,
                keySchema: new List <KeySchemaElement>
            {
                new KeySchemaElement
                {
                    AttributeName = "Id",
                    KeyType       = KeyType.HASH
                }
            },
                attributeDefinitions: new List <AttributeDefinition>
            {
                new AttributeDefinition()
                {
                    AttributeName = "Id",
                    AttributeType = ScalarAttributeType.S
                }
            },
                provisionedThroughput: new ProvisionedThroughput
            {
                ReadCapacityUnits  = 1,
                WriteCapacityUnits = 1
            }
                );

            try
            {
                using (var client = new AmazonDynamoDBClient(BasicAwsCredentials, AmazonDynamoDbConfig))
                {
                    var result = client.CreateTableAsync(request).Result;
                }
            }
            catch (ResourceInUseException)
            {
                SelfLog.WriteLine("Table already exists.");
            }
        }
예제 #7
0
        static IEnumerable <LogEventProperty> GetProperties(object value, ILogEventPropertyValueFactory recursive)
        {
            var valueType = value.GetType();
            var props     = valueType.GetProperties().Where(p => p.CanRead &&
                                                            p.GetGetMethod().IsPublic&&
                                                            !p.GetGetMethod().IsStatic);

            foreach (var prop in props)
            {
                object propValue;
                try
                {
                    propValue = prop.GetValue(value, null);
                }
                catch (TargetInvocationException ex)
                {
                    SelfLog.WriteLine("The property accessor {0} threw exception {1}", prop, ex);
                    propValue = "The property accessor threw an exception: " + ex.InnerException.GetType().Name;
                }
                yield return(new LogEventProperty(prop.Name, recursive.CreatePropertyValue(propValue, true)));
            }
        }
예제 #8
0
        public void writeAndRetry(string payload)
        {
            for (int i = 0; i < _clientConfig.MaxRetries; i++)
            {
                // backoff mechanism
                int backoffTime = (int)Math.Min(Math.Pow(i, 2), _clientConfig.MaxBackoff);
                if (backoffTime > 0)
                {
                    SelfLog.WriteLine("Making a new attempt in {0} seconds ({1}/{2})", backoffTime, i, _clientConfig.MaxRetries);
                }
                Thread.Sleep(backoffTime * 1000);


                if (_client == null || _client.Connected == false)
                {
                    try
                    {
                        connect();
                    }
                    catch (Exception e)
                    {
                        SelfLog.WriteLine("Exception while connecting client: {0}", e);
                        continue;
                    }
                }

                try
                {
                    byte[] data = UTF8.GetBytes(payload);
                    _stream.Write(data, 0, data.Length);
                    return;
                }
                catch (Exception e)
                {
                    SelfLog.WriteLine("Retry to send log event: {0}", e);
                }
            }
            SelfLog.WriteLine("Exception while sending log event, event dropped");
        }
예제 #9
0
        // connect to the specify endpoint
        private void connect()
        {
            SelfLog.WriteLine("Starting a new connection to {0}:{1} (SSL = {2})", _clientConfig.Ip, _clientConfig.Port, _clientConfig.UseSSL);
            try
            {
                _client = new TcpClient();
                _client.ConnectAsync(_clientConfig.Ip, _clientConfig.Port).Wait();

                _rawStream = _client.GetStream();


                if (_clientConfig.UseSSL)
                {
                    _sslStream = new SslStream(_rawStream);
                    _sslStream.AuthenticateAsClientAsync(_clientConfig.Ip).Wait();
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
예제 #10
0
        /// <summary>
        /// Construct a message template using manually-defined text and property tokens.
        /// </summary>
        /// <param name="text">The full text of the template; used by Serilog internally to avoid unneeded
        /// string concatenation.</param>
        /// <param name="tokens">The text and property tokens defining the template.</param>
        /// <exception cref="ArgumentNullException">When <paramref name="text"/> is <code>null</code></exception>
        /// <exception cref="ArgumentNullException">When <paramref name="tokens"/> is <code>null</code></exception>
        public MessageTemplate(string text, IEnumerable <MessageTemplateToken> tokens)
        {
            Text    = text ?? throw new ArgumentNullException(nameof(text));
            _tokens = (tokens ?? throw new ArgumentNullException(nameof(tokens))).ToArray();

            var propertyTokens = GetElementsOfTypeToArray <PropertyToken>(_tokens);

            if (propertyTokens.Length != 0)
            {
                var allPositional = true;
                var anyPositional = false;
                foreach (var propertyToken in propertyTokens)
                {
                    if (propertyToken.IsPositional)
                    {
                        anyPositional = true;
                    }
                    else
                    {
                        allPositional = false;
                    }
                }

                if (allPositional)
                {
                    PositionalProperties = propertyTokens;
                }
                else
                {
                    if (anyPositional)
                    {
                        SelfLog.WriteLine("Message template is malformed: {0}", text);
                    }

                    NamedProperties = propertyTokens;
                }
            }
        }
        /// <summary>
        /// Write log events to the specified file.
        /// </summary>
        /// <param name="sinkConfiguration">Logger sink configuration.</param>
        /// <param name="path">Path to the file.</param>
        /// <param name="restrictedToMinimumLevel">The minimum level for
        /// events passed through the sink. Ignored when <paramref name="levelSwitch"/> is specified.</param>
        /// <param name="levelSwitch">A switch allowing the pass-through minimum level
        /// to be changed at runtime.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
        /// <param name="fileSizeLimitBytes">The maximum size, in bytes, to which a log file will be allowed to grow.
        /// For unrestricted growth, pass null. The default is 1 GB.</param>
        /// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default
        /// is false.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <remarks>The file will be written using the UTF-8 character set.</remarks>
        public static LoggerConfiguration File(
            this LoggerSinkConfiguration sinkConfiguration,
            string path,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate          = DefaultOutputTemplate,
            IFormatProvider formatProvider = null,
            long?fileSizeLimitBytes        = DefaultFileSizeLimitBytes,
            LoggingLevelSwitch levelSwitch = null,
            bool buffered = false)
        {
            if (sinkConfiguration == null)
            {
                throw new ArgumentNullException(nameof(sinkConfiguration));
            }
            if (outputTemplate == null)
            {
                throw new ArgumentNullException(nameof(outputTemplate));
            }
            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            FileSink sink;

            try
            {
                sink = new FileSink(path, formatter, fileSizeLimitBytes, buffered: buffered);
            }
            catch (ArgumentException)
            {
                throw;
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Unable to open file sink for {0}: {1}", path, ex);
                return(sinkConfiguration.Sink(new NullSink()));
            }

            return(sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch));
        }
예제 #12
0
        /// <summary>
        /// Emit the provided log event to the sink.
        /// </summary>
        /// <param name="logEvent">The log event to write.</param>
        /// <remarks>
        /// <see cref="LogEventLevel.Debug" />, <see cref="LogEventLevel.Information" /> and <see cref="LogEventLevel.Verbose" /> are registered as <see cref="EventLogEntryType.Information" />.
        /// <see cref="LogEventLevel.Error" />, <see cref="LogEventLevel.Fatal" /> are registered as <see cref="EventLogEntryType.Error" />.
        /// <see cref="LogEventLevel.Warning" /> are registered as <see cref="EventLogEntryType.Warning" />.
        /// The Event ID in the Windows log will be set to the integer value of the <paramref name="logEvent"/>'s <see cref="LogEvent.Level"/> property, so that the log can be filtered with more granularity.</remarks>
        public void Emit(LogEvent logEvent)
        {
            if (logEvent == null)
            {
                throw new ArgumentNullException("logEvent");
            }

            EventLogEntryType type;

            switch (logEvent.Level)
            {
            case LogEventLevel.Debug:
            case LogEventLevel.Information:
            case LogEventLevel.Verbose:
                type = EventLogEntryType.Information;
                break;

            case LogEventLevel.Error:
            case LogEventLevel.Fatal:
                type = EventLogEntryType.Error;
                break;

            case LogEventLevel.Warning:
                type = EventLogEntryType.Warning;
                break;

            default:
                SelfLog.WriteLine("Unexpected logging level, writing to EventLog as Information");
                type = EventLogEntryType.Information;
                break;
            }

            var payload = new StringWriter();

            _textFormatter.Format(logEvent, payload);

            System.Diagnostics.EventLog.WriteEntry(_source, payload.ToString(), type, (int)logEvent.Level);
        }
        private async Task PumpAsync()
        {
            try {
                while (!_batchEventsCollection.IsCompleted)
                {
                    var logEvents = _batchEventsCollection.Take(_cancellationTokenSource.Token);
                    SelfLog.WriteLine($"Sending batch of {logEvents.Count} logs");

                    var retValue = await WriteLogEventAsync(logEvents).ConfigureAwait(false);

                    if (retValue)
                    {
                        Interlocked.Add(ref _numMessages, -1 * logEvents.Count);
                    }
                    else
                    {
                        SelfLog.WriteLine($"Retrying after {_transientThresholdSpan.TotalSeconds} seconds...");

                        await Task.Delay(_transientThresholdSpan).ConfigureAwait(false);

                        if (!_batchEventsCollection.IsAddingCompleted)
                        {
                            _batchEventsCollection.Add(logEvents);
                        }
                    }

                    if (_cancellationTokenSource.IsCancellationRequested)
                    {
                        _cancellationTokenSource.Token.ThrowIfCancellationRequested();
                    }
                }
            }
            catch (InvalidOperationException) { }
            catch (OperationCanceledException) { }
            catch (Exception ex) {
                SelfLog.WriteLine(ex.Message);
            }
        }
예제 #14
0
        private void SendBatchOneEventAtATime(IEnumerable <LogEvent> events)
        {
            foreach (var logEvent in events)
            {
                var eventData = ConvertLogEventToEventData(logEvent);

#if NET45
                if (eventData.SerializedSizeInBytes > GetAllowedMessageSize(1))
                {
                    SelfLog.WriteLine("Message too large to send with eventhub");
                    continue;
                }
#endif

                try
                {
#if NET45
                    using (new TransactionScope(TransactionScopeOption.Suppress))
                    {
                        _eventHubClient.Send(eventData);
                    }
#else
                    _eventHubClient.SendAsync(eventData).Wait();
#endif
                }
                catch
                {
                    try
                    {
                        Emit(logEvent);
                    }
                    catch
                    {
                        SelfLog.WriteLine("Could not Emit message");
                    }
                }
            }
        }
예제 #15
0
        private void FlushAndCloseEventHandlers()
        {
            try {
                SelfLog.WriteLine("Halting sink...");

                _eventCancellationToken.Cancel();
                _cancellationToken.Cancel();

                Task.WaitAll(_workerTasks.ToArray());

                _canStop = true;
                _timerResetEvent.Set();

                // Flush events collection
                while (_eventsCollection.TryTake(out LogEvent logEvent))
                {
                    _logEventBatch.Enqueue(logEvent);

                    if (_logEventBatch.Count >= _batchSize)
                    {
                        FlushLogEventBatch();
                    }
                }

                FlushLogEventBatch();

                // Flush events batch
                while (_batchEventsCollection.TryTake(out var eventBatch))
                {
                    WriteLogEventAsync(eventBatch).Wait(TimeSpan.FromSeconds(30));
                }

                Task.WaitAll(new[] { _eventPumpTask, _batchTask, _timerTask }, TimeSpan.FromSeconds(30));
            }
            catch (Exception ex) {
                SelfLog.WriteLine(ex.Message);
            }
        }
예제 #16
0
        /// <summary>
        /// Construct a sink posting to the Windows event log, creating the specified <paramref name="source"/> if it does not exist.
        /// </summary>
        /// <param name="source">The source name by which the application is registered on the local computer. </param>
        /// <param name="logName">The name of the log the source's entries are written to. Possible values include Application, System, or a custom event log.</param>
        /// <param name="textFormatter">Supplies culture-specific formatting information, or null.</param>
        /// <param name="machineName">The name of the machine hosting the event log written to.</param>
        /// <param name="manageEventSource">If false does not check/create event source.  Defaults to true i.e. allow sink to manage event source creation</param>
        /// <param name="eventIdProvider">Supplies event ids for emitted log events.</param>
        public EventLogSink(string source, string logName, ITextFormatter textFormatter, string machineName, bool manageEventSource, IEventIdProvider eventIdProvider)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (textFormatter == null)
            {
                throw new ArgumentNullException(nameof(textFormatter));
            }
            if (eventIdProvider == null)
            {
                throw new ArgumentNullException(nameof(eventIdProvider));
            }

            // The source is limitted in length and allowed chars, see: https://msdn.microsoft.com/en-us/library/e29k5ebc%28v=vs.110%29.aspx
            if (source.Length > MaximumSourceNameLengthChars)
            {
                SelfLog.WriteLine("Trimming long event log source name to {0} characters", MaximumSourceNameLengthChars);
                source = source.Substring(0, MaximumSourceNameLengthChars);
            }

            source = source.Replace("<", "_");
            source = source.Replace(">", "_");

            _eventIdProvider = eventIdProvider;
            _textFormatter   = textFormatter;
            _log             = new System.Diagnostics.EventLog(string.IsNullOrWhiteSpace(logName) ? ApplicationLogName : logName, machineName);

            if (manageEventSource)
            {
                ConfigureSource(_log, source);
            }
            else
            {
                _log.Source = source;
            }
        }
예제 #17
0
        private void EmitBatchChecked(ICollection <LogEvent> events)
        {
            if (events == null || !events.Any())
            {
                return;
            }

            string payload;

            using (var writer = new StringWriter())
            {
                writer.Write("[");
                var added = false;
                foreach (var evt in events)
                {
                    if (added)
                    {
                        writer.Write(",");
                    }
                    Formatter.Format(evt, writer);
                    added = true;
                }
                writer.Write("]");
                payload = writer.ToString();
            }


            var result = HttpClient
                         .SendAsync(CreateRequest(payload), HttpCompletionOption.ResponseContentRead)
                         .GetAwaiter().GetResult();

            if (!result.IsSuccessStatusCode)
            {
                var req     = result.RequestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                var content = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                SelfLog.WriteLine("Posting logs to NewRelic gave status code: {0} Payload: {1} Exception: {2}", result.StatusCode, req, content);
            }
        }
예제 #18
0
        /// <summary>
        ///     Construct a sink posting to the specified database.
        /// </summary>
        /// <param name="connectionString">Connection string to access the database.</param>
        /// <param name="tableName">Name of the table to store the data in.</param>
        /// <param name="includeProperties">Specifies if the properties need to be saved as well.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <param name="storeTimestampInUtc">Store Timestamp In UTC</param>
        /// <param name="additionalDataColumns">Additional columns for data storage.</param>
        /// <param name="autoCreateSqlTable">Create log table with the provided name on destination sql server.</param>
        public MSSqlServerSink(string connectionString, string tableName, bool includeProperties, int batchPostingLimit,
                               TimeSpan period, IFormatProvider formatProvider, bool storeTimestampInUtc, DataColumn[] additionalDataColumns = null,
                               bool autoCreateSqlTable = false)
            : base(batchPostingLimit, period)
        {
            if (string.IsNullOrWhiteSpace(connectionString))
            {
                throw new ArgumentNullException("connectionString");
            }

            if (string.IsNullOrWhiteSpace(tableName))
            {
                throw new ArgumentNullException("tableName");
            }

            _connectionString      = connectionString;
            _tableName             = tableName;
            _includeProperties     = includeProperties;
            _formatProvider        = formatProvider;
            _storeTimestampInUtc   = storeTimestampInUtc;
            _additionalDataColumns = additionalDataColumns;

            // Prepare the data table
            _eventsTable = CreateDataTable();

            if (autoCreateSqlTable)
            {
                try
                {
                    SqlTableCreator tableCreator = new SqlTableCreator(connectionString);
                    tableCreator.CreateTable(_eventsTable);
                }
                catch (Exception ex)
                {
                    SelfLog.WriteLine("Exception {0} caught while creating table {1} to the database specified in the Connection string.", (object)ex, (object)tableName);
                }
            }
        }
        /// <summary>
        ///     Emit a batch of log events, running asynchronously.
        /// </summary>
        /// <param name="events">The events to emit.</param>
        /// <remarks>
        ///     Override either <see cref="PeriodicBatchingSink.EmitBatch" /> or <see cref="PeriodicBatchingSink.EmitBatchAsync" />
        ///     ,
        ///     not both.
        /// </remarks>
        protected override async Task EmitBatchAsync(IEnumerable <LogEvent> events)
        {
            // Copy the events to the data table
            FillDataTable(events);

            try
            {
                using (var cn = new SqlConnection(_connectionString))
                {
                    await cn.OpenAsync().ConfigureAwait(false);

                    using (var copy = _columnOptions.DisableTriggers
                            ? new SqlBulkCopy(cn)
                            : new SqlBulkCopy(cn, SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers, null)
                           )
                    {
                        copy.DestinationTableName = string.Format("[{0}].[{1}]", _schemaName, _tableName);
                        foreach (var column in _eventsTable.Columns)
                        {
                            var columnName = ((DataColumn)column).ColumnName;
                            var mapping    = new SqlBulkCopyColumnMapping(columnName, columnName);
                            copy.ColumnMappings.Add(mapping);
                        }

                        await copy.WriteToServerAsync(_eventsTable).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Unable to write {0} log events to the database due to following error: {1}", events.Count(), ex.Message);
            }
            finally
            {
                // Processed the items, clear for the next run
                _eventsTable.Clear();
            }
        }
예제 #20
0
        void OnTick()
        {
            try
            {
                do
                {
                    var      count  = 0;
                    var      events = new Queue <LogEvent>();
                    LogEvent next;
                    while (count < _batchSizeLimit && _queue.TryDequeue(out next))
                    {
                        count++;
                        events.Enqueue(next);
                    }

                    if (events.Count == 0)
                    {
                        return;
                    }

                    EmitBatch(events);
                }while (true);
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex);
            }
            finally
            {
                lock (_stateLock)
                {
                    if (!_unloading)
                    {
                        SetTimer();
                    }
                }
            }
        }
예제 #21
0
        protected override async Task EmitBatchAsync(IEnumerable<LogEvent> events)
        {
            try
            {
                using (var conn = new SqliteConnection(_connectionString))
                {
                    await conn.OpenAsync();
                    using (var tran = conn.BeginTransaction())
                    {
                        using (var cmdLogEntry = CreateLogEntryInsertCommand(conn, tran))
                        using (var cmdLogEntryProperty = CreateLogEntryPropertyInsertCommand(conn, tran))
                        {
                            foreach (var logEvent in events)
                            {
                                // Do not log events that were generated from browsing Sejil URL.
                                if (logEvent.Properties.Any(p => (p.Key == "RequestPath" || p.Key == "Path") &&
                                    p.Value.ToString().Contains(_uri)))
                                {
                                    continue;
                                }

                                var logId = await InsertLogEntryAsync(cmdLogEntry, logEvent);
                                foreach (var property in logEvent.Properties)
                                {
                                    await InsertLogEntryPropertyAsync(cmdLogEntryProperty, logId, property);
                                }
                            }
                        }
                        tran.Commit();
                    }
                    conn.Close();
                }
            }
            catch (Exception e)
            {
                SelfLog.WriteLine(e.Message);
            }
        }
        static IEnumerable <TemplateProperty> GetProperties(
            object value, IMessageTemplatePropertyValueFactory recursive)
        {
            var properties =

#if !REFLECTION_API_EVOLVED
                // TODO: stop using LINQ
                value.GetType().GetProperties().Where(p => p.CanRead &&
                                                      p.GetGetMethod().IsPublic&&
                                                      !p.GetGetMethod().IsStatic&&
                                                      (p.Name != "Item" || p.GetIndexParameters().Length == 0));
#else
                value.GetType().GetPropertiesRecursive();
#endif
            foreach (var prop in properties)
            {
                object propValue;
                try
                {
#if !REFLECTION_API_EVOLVED // https://blogs.msdn.microsoft.com/dotnet/2012/08/28/evolving-the-reflection-api/
                    propValue = prop.GetValue(value, null);
#else
                    propValue = prop.GetValue(value);
#endif
                }
                catch (TargetParameterCountException)
                {
                    SelfLog.WriteLine("The property accessor {0} is a non-default indexer", prop);
                    continue;
                }
                catch (TargetInvocationException ex)
                {
                    SelfLog.WriteLine("The property accessor {0} threw exception {1}", prop, ex);
                    propValue = "The property accessor threw an exception: " + ex.InnerException.GetType().Name;
                }
                yield return(new TemplateProperty(prop.Name, recursive.CreatePropertyValue(propValue, true)));
            }
        }
예제 #23
0
        /// <summary>
        /// Send payload to Datadog logs-backend.
        /// </summary>
        /// <param name="payload">Payload to send.</param>
        public async Task WriteAsync(string payload)
        {
            for (int retry = 0; retry < MaxRetries; retry++)
            {
                int backoff = (int)Math.Min(Math.Pow(retry, 2), MaxBackoff);
                if (retry > 0)
                {
                    await Task.Delay(backoff * 1000);
                }

                if (IsConnectionClosed())
                {
                    try
                    {
                        await ConnectAsync();
                    }
                    catch (Exception e)
                    {
                        SelfLog.WriteLine("Could not connect to Datadog: {0}", e);
                        continue;
                    }
                }

                try
                {
                    SelfLog.WriteLine("Sending payload to Datadog: {0}", payload);
                    byte[] data = UTF8.GetBytes(payload);
                    _stream.Write(data, 0, data.Length);
                    return;
                }
                catch (Exception e)
                {
                    CloseConnection();
                    SelfLog.WriteLine("Could not send data to Datadog: {0}", e);
                }
            }
            SelfLog.WriteLine("Could not send payload to Datadog: {0}", payload);
        }
        public override void Format(IEnumerable <string> logEvents, TextWriter output)
        {
            if (logEvents == null)
            {
                throw new ArgumentNullException(nameof(logEvents));
            }
            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (!logEvents.Any())
            {
                SelfLog.WriteLine("log event is empty.");
                return;
            }

            output.Write("[{\"logs\": [");

            var delimStart = string.Empty;

            foreach (var logEvent in logEvents)
            {
                if (string.IsNullOrWhiteSpace(logEvent))
                {
                    continue;
                }

                if (CheckEventBodySize(logEvent))
                {
                    output.Write(delimStart);
                    output.Write(logEvent);
                    delimStart = ",";
                }
            }

            output.Write("]}]");
        }
예제 #25
0
        /// <summary>
        /// Converts specified address or hostname into an <see cref="IPAddress"/>.
        /// </summary>
        /// <param name="address">The address to convert.</param>
        /// <returns>
        /// An <see cref="IPAddress"/> if address is found to be a valid IP address or DNS name;
        /// otherwise null.
        /// </returns>
        public static IPAddress ToIPAddress(this string address)
        {
            if (IPAddress.TryParse(address, out var ipAddress))
            {
                return(ipAddress);
            }

            try
            {
                // TODO: Use Dns.GetHostEntry when moving to .NET Standard 2.0
                var hostEntry = Dns.GetHostEntryAsync(address).Result;

                return(hostEntry
                       .AddressList
                       .FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork));
            }
            catch (Exception e)
            {
                SelfLog.WriteLine("Unable to lookup hostname {0}: {1}", address, e);
            }

            return(null);
        }
예제 #26
0
        public void Emit(LogEvent logEvent)
        {
            List <Exception> exceptions = null;

            foreach (var sink in _sinks)
            {
                try
                {
                    sink.Emit(logEvent);
                }
                catch (Exception ex)
                {
                    SelfLog.WriteLine("Caught exception while emitting to sink {0}: {1}", sink, ex);
                    exceptions = exceptions ?? new List <Exception>();
                    exceptions.Add(ex);
                }
            }

            if (exceptions != null)
            {
                throw new AggregateException("Failed to emit a log event.", exceptions);
            }
        }
예제 #27
0
        /// <summary>
        /// Posts the messages.
        /// </summary>
        /// <param name="messages">The messages.</param>
        /// <returns>A <see cref="Task"/> representing any asynchronous operation.</returns>
        private async Task PostMessages(IEnumerable <MicrosoftExtendedLogEvent> messages)
        {
            // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
            foreach (var logEvent in messages)
            {
                try
                {
                    var message = this.CreateMessage(logEvent);
                    var json    = JsonSerializer.Serialize(message, JsonSerializerOptions);
                    var result  = await this.client.PostAsync(this.options.WebHookUri, new StringContent(json, Encoding.UTF8, "application/json")).ConfigureAwait(false);

                    if (!result.IsSuccessStatusCode)
                    {
                        throw new LoggingFailedException($"Received failed result {result.StatusCode} when posting events to Microsoft Teams.");
                    }
                }
                catch (Exception ex)
                {
                    SelfLog.WriteLine($"{ex.Message}, {ex.StackTrace}");
                    this.options.FailureCallback?.Invoke(ex);
                }
            }
        }
예제 #28
0
        protected override async Task EmitBatchAsync(IEnumerable <LogEvent> events)
        {
            try
            {
                using (var connection = new MySqlConnection(_connectionString))
                {
                    await connection.OpenAsync().ConfigureAwait(false);

                    if (_useBulkInsert)
                    {
                        await BulkInsert(events, connection).ConfigureAwait(false);
                    }
                    else
                    {
                        await Insert(events, connection).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Unable to write {0} log events to the database due to following error: {1}", events.Count(), ex.Message);
            }
        }
        protected async Task EnsureConnectedAsync()
        {
            try
            {
                bool endpointInitialzied = _endpoint?.IsConnected() ?? false;

                if (endpointInitialzied)
                {
                    return;
                }

                InitializeEndpoint();

                await _endpoint.ConnectAsync();

                _stream  = _endpoint.GetStream();
                _emitter = new FluentdEmitter(_stream);
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine($"[Serilog.Sinks.Fluentd] Connection exception {ex.Message}\n{ex.StackTrace}");
            }
        }
예제 #30
0
        private void CreateTable(MySqlConnection sqlConnection)
        {
            try
            {
                var tableCommandBuilder = new StringBuilder();
                tableCommandBuilder.Append($"CREATE TABLE IF NOT EXISTS {_tableName} (");
                tableCommandBuilder.Append("id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,");
                tableCommandBuilder.Append("Timestamp VARCHAR(100),");
                tableCommandBuilder.Append("Level VARCHAR(15),");
                tableCommandBuilder.Append("Message TEXT,");
                tableCommandBuilder.Append("Exception TEXT,");
                tableCommandBuilder.Append("Properties TEXT,");
                tableCommandBuilder.Append("_ts TIMESTAMP)");

                var cmd = sqlConnection.CreateCommand();
                cmd.CommandText = tableCommandBuilder.ToString();
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine(ex.Message);
            }
        }