serilog-contrib / serilog-sinks-slack Goto Github PK
View Code? Open in Web Editor NEWA simple (yet customizable) Slack logging sink for Serilog
License: MIT License
A simple (yet customizable) Slack logging sink for Serilog
License: MIT License
I have two Slack Sinks that log to different Channels.
One Channel is for logs and the other is for alerts. Like below:
.WriteTo.Slack(
webhookUrl: "https://hooks.slack.com/services/hook1",
//hook for alerting CST
customChannel: "aletr",
customUsername: $"alert-bot",
customIcon: ":radioactive_sign:",
restrictedToMinimumLevel: LogEventLevel.Fatal
)
.WriteTo.Slack(
webhookUrl: "https://hooks.slack.com/services/hook2",
customChannel: "logs",
customUsername: $"log-bot",
customIcon: ":radioactive_sign:",
restrictedToMinimumLevel: LogEventLevel.Error
);
Currently I am managing this by making the alert Channels log level as Fatal. But I wan to log Certain Errors as Alerts.
But I cant do that directly as then I will have decrease the logLevel for Alert Channel and it will be polluted by all the Error Logs
First of all thank you for the great sink.
I've used it and noticed that if the the stack trace of an exception is too long, the message gets cut and the formatting gets lost: the texts starts with ``` but the matching end markdown is never reached (I see ...). Would it be possible to limit the message correctly in order to display the stack trace correctly formatted? It may even be interesting to have a max char configuration for this (since I don't know if this is configurable in Slack).
I have a console app that executes quite quickly and the number of messages is inconsistently relayed to Slack. (i.e out of 6 log messages, sometimes I might see 1 or 2 or 3 but never the full 6.
I understand the limitations of posting to a webhook but I thought that as long as I am disposing correctly that the sink would be fully flushed? Maybe a synchronous option if people really want this enforced?
Thoughts?
I tried using the sink using https://github.com/serilog/serilog-settings-configuration but it didn't work:
"Serilog": {
"MinimumLevel": {
"Default": "Debug",
"Override": {
"Microsoft": "Information",
"System": "Information"
}
},
"WriteTo": [
{
"Name": "Slack",
"Args": {
"WebHookUrl": "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
}
]
}
I have implemented this in our web app project. I want to log Post Api body details in the error to have details about the API call. But right now there are only some fixed parameters that are auto-generated.
It would be good if each log level (info, debug, trace, warning, error, critical, etc) could have their own channel specified to send messages to.
When building a strong-named assembly referencing this sink, one will get the warning below during the build.
CSC : warning CS8002: Referenced assembly 'Serilog.Sinks.Slack, Version=1.2.56.0, Culture=neutral, PublicKeyToken=null' does not have a strong name.
Signing the assembly with a strong name is a best practice, and would cause no side-effects whatsoever to anyone.
Currently, the timestamp attachment is not formatted and is just written as DateTimeOffset.ToString()
, which is depending on the culture of the current thread.
https://github.com/mgibas/serilog-sinks-slack/blob/master/Serilog.Sinks.Slack/SlackSink.cs#L89
new Field{Title = "Timestamp", Value = logEvent.Timestamp.ToString(), Short = _options.DefaultAttachmentsShortFormat}
Would it be possible to add support for custom timestamp attachment formats, so you can use any format you like, without having to rely on the current machine culture?
The Serilog.Sinks.Slack
NuGet package doesn't yet have an icon.
I suggest using the standard icon for sinks:
More details: https://github.com/serilog-contrib/brand
I'm fine with Slack receiveing at most one error every half an hour and I don't want all the other errors to buildup in the queue and consume application memory.
Please expose the QueueLimit property from the PeriodicBatchingSinkOptions in your SlackSinkOptions.
Thanks!
When I set my logger up to sink to a webhook, it works when I test it inside visual studio.
The moment I build it however and run the executable, the webhook gets no messages whatsoever.
I've tried both Debug and Release mode, none seem to work.
[edit]: when running the build in .net 4.6.1 it doesn't work, however it works with .net core 1.1
When using Serilog.Sinks.Slack
together with the latest version of Serilog.Sinks.PeriodicBatching
the call to Serilog.Log.CloseAndFlush()
will crash with a StackOverflowException
because the SlackSink
Dispose
method will call Dispose
on PeriodicBatchSink
which in turn calls Dispose
on SlackSink
, causing an endless loop.
This issue was discovered while using the Sink in a .NET Framework application where transient dependencies have to be explicitly included and where the dependency was updated to the latest version.
From my research into how PeriodicBatching
code works and how other Sinks handle this it seems that maybe SinkSlack
should be split up so that it doesn't pass a reference to itself to PeriodicBatchingSink
. But I'm not sure how this change would affect people who use this library today.
Here is the sample code I used to reproduce the issue:
using Serilog;
using Serilog.Events;
using Serilog.Sinks.Slack;
using Serilog.Sinks.Slack.Models;
namespace SlackSinkStackOverflow;
internal static class Program
{
private static void Main()
{
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.Slack(new SlackSinkOptions
{ WebHookUrl = "https://hooks.slack.com/services/...", MinimumLogEventLevel = LogEventLevel.Error })
.CreateLogger();
try
{
Log.Information("Starting application");
}
catch (Exception exception)
{
Log.Fatal(exception, "Application terminated unexpectedly");
}
finally
{
// Causes a StackOverflowException
Log.CloseAndFlush();
}
}
}
Serilog.Sinks.Slack
version is 2.2.2.
Serilog.Sinks.PeriodicBatching
version is 5.0.0
A suggested solution would look something similar to the following code:
public class SlackMessageFormatter
{
private readonly SlackSinkOptions _options;
private readonly ITextFormatter _textFormatter;
public SlackMessageFormatter(SlackSinkOptions options, ITextFormatter textFormatter)
{
_options = options;
_textFormatter = textFormatter;
}
public Message CreateMessage(LogEvent logEvent)
{
using (var textWriter = new StringWriter())
{
_textFormatter.Format(logEvent, textWriter);
return new Message
{
Text = textWriter.ToString(),
// Set other properties...
};
}
}
// Add methods for creating attachments, etc.
}
public class SlackClient : IDisposable
{
private readonly HttpClient _httpClient;
public SlackClient()
{
_httpClient = new HttpClient();
}
public async Task SendMessageAsync(string webhookUrl, Message message)
{
var json = JsonConvert.SerializeObject(message);
await _httpClient.PostAsync(webhookUrl, new StringContent(json));
}
public void Dispose()
{
_httpClient.Dispose();
}
}
public class SlackBatchingSink : IBatchedLogEventSink, IDisposable
{
private readonly SlackMessageFormatter _formatter;
private readonly SlackClient _client;
private readonly SlackSinkOptions _options;
public SlackBatchingSink(SlackMessageFormatter formatter, SlackClient client, SlackSinkOptions options)
{
_formatter = formatter;
_client = client;
_options = options;
}
public async Task EmitBatchAsync(IEnumerable<LogEvent> events)
{
foreach (var logEvent in events)
{
var message = _formatter.CreateMessage(logEvent);
await _client.SendMessageAsync(_options.WebHookUrl, message);
}
}
public Task OnEmptyBatchAsync()
{
return Task.CompletedTask;
}
public void Dispose()
{
_client.Dispose();
}
}
public class SlackSink : ILogEventSink, IDisposable
{
private readonly PeriodicBatchingSink _periodicBatchingSink;
public SlackSink(SlackSinkOptions options, ITextFormatter textFormatter)
{
var formatter = new SlackMessageFormatter(options, textFormatter);
var client = new SlackClient();
var batchingSink = new SlackBatchingSink(formatter, client, options);
_periodicBatchingSink = new PeriodicBatchingSink(batchingSink, options.ToPeriodicBatchingSinkOptions());
}
public void Emit(LogEvent logEvent)
{
_periodicBatchingSink.Emit(logEvent);
}
public void Dispose()
{
_periodicBatchingSink.Dispose();
}
}
Benefits of the Redesign:
Each class now has a single responsibility, making the code easier to understand, maintain, and test.
The SlackSink no longer directly manages both its disposal and that of its components. The components (like SlackClient and PeriodicBatchingSink) handle their own lifecycles independently, reducing the risk of recursive disposal calls.
The SlackMessageFormatter and SlackClient can be reused or tested independently, providing more flexibility in the codebase.
Simplified Debugging:
If a stack overflow or other issue does occur, itβs easier to isolate the problem to a specific component, as each class now handles a distinct part of the process.
This redesign should help eliminate the stack overflow problem while also improving the overall architecture and maintainability of your logging infrastructure.
I would like to use this project but I need to know under which license I can use it.
I have used your sink in my application and it was working fine, it has now stopped working at all, I get no exception and nothing strange in Output (visual Studio).
I then tried your example application with my Webhook and that isn't working either, I have tested my Slack Webhook in Command Prompt and it is working fine.
Is anyone else seeing this?
I've started using this project and I've noticed that alerts are not slacked before my console application exit.
I'm not sure if this is a bug? Or is this the expected behavior?
For now, I've added a thread sleep before exit but I'd like to know if it's a bug and if not how people using this library usually account for this...?
I've been using another slack sink (ServiceStack.Logging.Slack) and all slack alerts are slacked properly before the application exit without adding a thread sleep.
But I need to use ServiceStack.Logging.Serilog and if I want to use Slack I need to use serilog-sinks-slack with it.
It seems it's possible to do this without adding a Thread sleep since it works with the default ServiceStack.Logging.Slack.
Thanks for any pointers ;-)
I haven't really dug into the problem yet but the symptoms first showed when a service wouldn't start up. Running the exe interactively resulted in:
Stack overflow.
Repeat 8733 times:
--------------------------------
at Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink.Dispose()
at Serilog.Sinks.Slack.SlackSink.Dispose(Boolean)
at Serilog.Sinks.Slack.SlackSink.Dispose()
--------------------------------
at Serilog.LoggerConfiguration+<>c__DisplayClass33_0.<CreateLogger>g__Dispose|1()
at Serilog.Extensions.Hosting.ReloadableLogger.Reload(System.Func`2<Serilog.LoggerConfiguration,Serilog.LoggerConfiguration>)
at Serilog.SerilogServiceCollectionExtensions+<>c__DisplayClass3_0.<AddSerilog>b__0(System.IServiceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier)
at System.Collections.Concurrent.ConcurrentDictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetOrAdd(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, System.Func`2<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier,System.__Canon>)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(System.Type)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider, System.Type)
at Serilog.SerilogServiceCollectionExtensions+<>c__DisplayClass3_0.<AddSerilog>b__2(System.IServiceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ConstructorCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier)
at System.Collections.Concurrent.ConcurrentDictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetOrAdd(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, System.Func`2<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier,System.__Canon>)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(System.Type)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider, System.Type)
at Microsoft.Extensions.Hosting.HostBuilder+<>c__DisplayClass35_0.<PopulateServiceCollection>b__2(System.IServiceProvider)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].VisitCallSite(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.RuntimeResolverContext)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceCallSite, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier)
at System.Collections.Concurrent.ConcurrentDictionary`2[[Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetOrAdd(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, System.Func`2<Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier,System.__Canon>)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceIdentifier, Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(System.Type)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(System.IServiceProvider, System.Type)
at Microsoft.Extensions.Hosting.HostBuilder.ResolveHost(System.IServiceProvider, System.Diagnostics.DiagnosticListener)
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at System.Linq.Utilities+<>c__DisplayClass2_0`3[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<CombineSelectors>b__0(System.__Canon)
at System.Linq.Enumerable+SelectArrayIterator`2[[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Threading.Tasks.Task.WhenAll(System.Collections.Generic.IEnumerable`1<System.Threading.Tasks.Task>)
at ServiceBase.ServiceHost+<RunBackgroundServices>d__1.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[ServiceBase.ServiceHost+<RunBackgroundServices>d__1, ServiceBase, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<RunBackgroundServices>d__1 ByRef)
at ServiceBase.ServiceHost.RunBackgroundServices(System.Collections.Generic.IEnumerable`1<System.Action`2<Microsoft.Extensions.Hosting.HostBuilderContext,Microsoft.Extensions.DependencyInjection.IServiceCollection>>)
at Program+<<Main>$>d__0.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Program+<<Main>$>d__0, ItemWorker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](<<Main>$>d__0 ByRef)
at Program.<Main>$(System.String[])
at Program.<Main>(System.String[])
today, only the Level and the Timestamp are hard coded sent to slack.
what if my log message look like this:
_logger.LogInformation("{ClientIp} has Joined", IP);
i would expect to have another field ClientIp (the same as ElasticSerach Sink does).
any chance to have this in the next drop?
The current implementation uses Serilog's PeriodicBatchingSink. It is set up to receive a message batch, loop the collection, sending each message as a separate HTTP request (a Slack limitation, the API only allows one message).
This isn't a good use case for PeriodicBatchingSink, because if we have a batch of 10 messages, and HTTP request 9 out of 10 is throttled by Slack and fails, the batching sink will retry the entire batch. This will duplicate messages 1 - 8 until all requests for the batch succeed.
What the sink really needs to do is post one at a time, in a way Serilog can retry. Needs some investigation - maybe we can just set the batch size to 1?
Based on a reproducible report by @GFoley83 in issue #23 . The following code should work (and does on .NET Core) but does not when targetting .NET Framework 4.5.2
var config = new LoggerConfiguration().WriteTo.Slack("https://hooks.slack.com/services/XXX");
Log.Logger = config.CreateLogger();
Log.Logger.Information("Hello world");
Log.CloseAndFlush();
Hi,
we recently introduced Slack in our company and I would love to output Error/Fatal log messages into a channel. I managed to do so with this sink in minutes. π
While fiddling around with it I tried to set an outputeTemplate
parameter to control the rendered text messages in the logs, but couldn't find any such parameter. Does this sink not support this?
I want to have several web services log into a single channel and without contextual information like the SourceContext
or a RequestID
in the log message it would be impossible to tell from which web service a log came or what's related.
Could you add this parameter to support the typical way of formatting the log messages in Serilog?
Kind regards
Michael
I was wondering why you're using NETStandard.Library for v.4.6 ?
I don't seem to be able to update the package for a solution ASP.NET MVC 4.6.
Hi guys, thanks for merging my last pull request! The new version wasn't published to NuGet, unfortunately, due to this error.
π error: Response status code does not indicate success: 403
(The specified API key is invalid, has expired, or does not have permission to access the specified package.).
Would you please check it? You can see the full log here:
https://github.com/serilog-contrib/serilog-sinks-slack/runs/5202446259?check_suite_focus=true
Thanks!
Moreno
Does this issue relate to a new feature or an existing bug?
Bug
What version of Serilog.Sinks.Elasticsearch is affected?
2.0.3
What is the target framework and operating system?
Net Core 3.1
Please describe the current behavior?
When using minimumLogEventLevel via json based configuration the set value is neither checked nor used. All events are being sent.
a minimal demo of the problem
create empty project
install Serilog
install Serilog.Sinks.Slak
configure something like this:
{
"Name": "Slack",
"Args": {
"WebHookUrl": "https://hooks.slack.com/services/XXXXX",
"CustomChannel": "#errors",
"CustomUserName": "User",
"MinimumLogEventLevel": "Warning",
"BatchSizeLimit": 1,
"ShowExceptionAttachments": true
}
you will find all logs in the channel
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.