static void Main(string[] args) { ExcludeFields ef = new ExcludeFields() { FirstName = "Jack", LastName = "Makan", EmployeeID = 100, Designation = "SSE", Address = "United States" }; List <string> discardedFieldsList = new List <string>(); discardedFieldsList.Add("FirstName"); discardedFieldsList.Add("Designation"); discardedFieldsList.Add("Address"); var log = new LoggerConfiguration() .WriteTo.Loggly() .CreateLogger(); ILogglyClient _loggly = new LogglyClient(); var logEvent = new LogglyEvent(); logEvent.Data.Add("message", "Simple message at {0}"); logEvent.Data.Add("context", ef.excludeFields(JsonConvert.SerializeObject(ef), discardedFieldsList)); logEvent.Data.Add("Error", new Exception("your exception message")); for (int i = 0; i < 10; i++) { _loggly.Log(logEvent); } Console.ReadKey(); }
/// <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 logglyEvent = new LogglyEvent(); var isHttpTransport = LogglyConfig.Instance.Transport.LogTransport == LogTransport.Https; logglyEvent.Syslog.Level = ToSyslogLevel(logEvent); foreach (var key in logEvent.Properties.Keys) { var propertyValue = logEvent.Properties[key]; var simpleValue = LogglyPropertyFormatter.Simplify(propertyValue); logglyEvent.Data.AddIfAbsent(key, simpleValue); } logglyEvent.Data.AddIfAbsent("Message", logEvent.RenderMessage(_formatProvider)); if (isHttpTransport) { // syslog will capture these via the header logglyEvent.Data.AddIfAbsent("Level", logEvent.Level.ToString()); } if (logEvent.Exception != null) { logglyEvent.Data.AddIfAbsent("Exception", logEvent.Exception); } _client.Log(logglyEvent); }
protected override void Write(LogEventInfo logEvent) { var loggly = new LogglyClient(); // The unwrapped event has a zero sequenceId, grab it before unwrapping; var sequenceId = logEvent.SequenceID; logEvent = GetCorrectEvent(logEvent); if (logEvent.Properties.ContainsKey("syslog-suppress")) { /* * logging delimiting messages like "--------------" makes sense for pretty printing to file log targets * but not so much for loggly. Support suppression. */ return; } var logMessage = Layout.Render(logEvent); var logglyEvent = new LogglyEvent(); var isHttpTransport = LogglyConfig.Instance.Transport.LogTransport == LogTransport.Https; logglyEvent.Timestamp = logEvent.TimeStamp; logglyEvent.Syslog.MessageId = sequenceId; logglyEvent.Syslog.Level = ToSyslogLevel(logEvent.Level); if (logEvent.Exception != null) { logglyEvent.Data.Add("exception", logEvent.Exception); } if (isHttpTransport) { // syslog will capture these via the header logglyEvent.Data.Add("sequenceId", sequenceId); logglyEvent.Data.Add("level", logEvent.Level.Name); } logglyEvent.Data.Add("message", logMessage); foreach (var tag in Tags.Split(',')) { logglyEvent.Options.Tags.Add(new SimpleTag { Value = tag }); } foreach (var key in logEvent.Properties.Keys) { logglyEvent.Data.AddIfAbsent(key.ToString(), logEvent.Properties[key]); } loggly.Log(logglyEvent); }
public async Task SelfReferencingLoopShouldNotFailMessageSerialization() { var transportMock = new Mock <IMessageTransport>(); transportMock.Setup(x => x.Send(It.IsAny <IEnumerable <LogglyMessage> >())) .Callback((IEnumerable <LogglyMessage> x) => x.ToList()) //making sure the messages are evaluated .Returns(() => Task.FromResult(new LogResponse { Code = ResponseCode.Success })); var logglyEvent = new LogglyEvent(); logglyEvent.Data.AddIfAbsent("ReferenceLoopType", new TypeWithReferenceLoopParent()); var client = new LogglyClient(transportMock.Object); var res = await client.Log(logglyEvent); Assert.AreEqual(ResponseCode.Success, res.Code); }
public void LogglyClientSendException() { var config = LogglyConfig.Instance; config.CustomerToken = "83fe7674-f87d-473e-a8af-bbbbbbbbbbbb"; config.ApplicationName = $"test"; config.Transport.EndpointHostname = "logs-01.loggly.com"; config.Transport.EndpointPort = 443; config.Transport.LogTransport = LogTransport.Https; var ct = new ApplicationNameTag { Formatter = "application-{0}" }; config.TagConfig.Tags.Add(ct); var logglyClient = new LogglyClient(); try { ThrowException(); } catch (Exception e) { LogglyEvent logglyEvent = new LogglyEvent { Timestamp = DateTimeOffset.UtcNow, Syslog = { Level = Level.Emergency } }; logglyEvent.Data.AddIfAbsent("Message", "xZx"); logglyEvent.Data.AddIfAbsent("Level", "Error"); logglyEvent.Data.AddIfAbsent("Exception", e); var res = logglyClient.Log(logglyEvent).Result; Assert.Equal(ResponseCode.Success, res.Code); } Thread.Sleep(5000); }
async Task OnTick() { LogEventLevel?minimumAcceptedLevel = LogEventLevel.Debug; try { //we'll use this to control the number of events read per cycle. If the batch limit is reached, //then there is probably more events queued and we should continue to read them. Otherwise, // we can wait for the next timer tick moment to see if anything new is available. int numberOfEventsRead; do { //this should consistently return the same batch of events until //a MarkAsProcessed message is sent to the provider. Never return a null, please... var payload = _bufferDataProvider.GetNextBatchOfEvents(); numberOfEventsRead = payload.Count(); if (numberOfEventsRead > 0) { //send the loggly events through the bulk API var result = await _logglyClient.Log(payload).ConfigureAwait(false); if (result.Code == ResponseCode.Success) { _connectionSchedule.MarkSuccess(); _bufferDataProvider.MarkCurrentBatchAsProcessed(); } else if (result.Code == ResponseCode.Error) { // The connection attempt was successful - the payload we sent was the problem. _connectionSchedule.MarkSuccess(); _bufferDataProvider.MarkCurrentBatchAsProcessed(); //move foward _invalidPayloadLogger.DumpInvalidPayload(result, payload); } else { _connectionSchedule.MarkFailure(); SelfLog.WriteLine("Received failed HTTP shipping result {0}: {1}", result.Code, result.Message); break; } } else { // For whatever reason, there's nothing waiting to send. This means we should try connecting again at the // regular interval, so mark the attempt as successful. _connectionSchedule.MarkSuccess(); // not getting any batch may mean our marker is off, or at the end of the current, old file. // Try to move foward and cleanup _bufferDataProvider.MoveBookmarkForward(); } } while (numberOfEventsRead == _batchPostingLimit); //keep sending as long as we can retrieve a full batch. If not, wait for next tick } catch (Exception ex) { SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex); _connectionSchedule.MarkFailure(); } finally { lock (_stateLock) { _controlledSwitch.Update(minimumAcceptedLevel); if (!_unloading) { SetTimer(); } } } }
/// <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) { await _client.Log(events.Select(_converter.CreateLogglyEvent)); }
async Task OnTick() { LogEventLevel?minimumAcceptedLevel = LogEventLevel.Debug; try { // Locking the bookmark ensures that though there may be multiple instances of this // class running, only one will ship logs at a time. using (var bookmark = IOFile.Open(_bookmarkFilename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read)) { using (var bookmarkStreamReader = new StreamReader(bookmark, Encoding.UTF8, false, 128)) { using (var bookmarkStreamWriter = new StreamWriter(bookmark)) { int count; do { count = 0; long nextLineBeginsAtOffset; string currentFile; TryReadBookmark(bookmark, bookmarkStreamReader, out nextLineBeginsAtOffset, out currentFile); var fileSet = GetFileSet(); if (currentFile == null || !IOFile.Exists(currentFile)) { nextLineBeginsAtOffset = 0; currentFile = fileSet.FirstOrDefault(); } if (currentFile == null) { continue; } //grab the list of pending LogglyEvents from the file var payload = GetListOfEvents(currentFile, ref nextLineBeginsAtOffset, ref count); if (count > 0) { //sen the loggly events through the bulk API var result = await _logglyClient.Log(payload).ConfigureAwait(false); if (result.Code == ResponseCode.Success) { _connectionSchedule.MarkSuccess(); WriteBookmark(bookmarkStreamWriter, nextLineBeginsAtOffset, currentFile); } else if (result.Code == ResponseCode.Error) { // The connection attempt was successful - the payload we sent was the problem. _connectionSchedule.MarkSuccess(); DumpInvalidPayload(result, payload); WriteBookmark(bookmarkStreamWriter, nextLineBeginsAtOffset, currentFile); } else { _connectionSchedule.MarkFailure(); SelfLog.WriteLine("Received failed HTTP shipping result {0}: {1}", result.Code, result.Message); break; } } else { // For whatever reason, there's nothing waiting to send. This means we should try connecting again at the // regular interval, so mark the attempt as successful. _connectionSchedule.MarkSuccess(); // Only advance the bookmark if no other process has the // current file locked, and its length is as we found it. if (fileSet.Length == 2 && fileSet.First() == currentFile && IsUnlockedAtLength(currentFile, nextLineBeginsAtOffset)) { WriteBookmark(bookmarkStreamWriter, 0, fileSet[1]); } if (fileSet.Length > 2) { // Once there's a third file waiting to ship, we do our // best to move on, though a lock on the current file // will delay this. IOFile.Delete(fileSet[0]); } } } while (count == _batchPostingLimit); } } } } catch (Exception ex) { SelfLog.WriteLine("Exception while emitting periodic batch from {0}: {1}", this, ex); _connectionSchedule.MarkFailure(); } finally { lock (_stateLock) { _controlledSwitch.Update(minimumAcceptedLevel); if (!_unloading) { SetTimer(); } } } }