GithubHelp home page GithubHelp logo

serilog-contrib / serilog-sinks-slack Goto Github PK

View Code? Open in Web Editor NEW
39.0 39.0 26.0 131 KB

A simple (yet customizable) Slack logging sink for Serilog

License: MIT License

C# 100.00%
serilog serilog-sink slack

serilog-sinks-slack's People

Contributors

alanedwardes avatar aperebus avatar brightsoul avatar dependabot[bot] avatar gabrielschmith avatar kimsey0 avatar mgibas avatar mirzamerdovic avatar phnx47 avatar seirysjs avatar trapperhell avatar tvance-vant4ge avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

serilog-sinks-slack's Issues

Upgrading to the latest version of Serilog causes infinite loop

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[])

Can we show Event properties fullscreen?

Hi,

Here is Slack screenshots from pc, can we make Event property values fill the width so I don't need to scroll too much :) and it's hard to read the message too.
slack
slack1

Add Message Token as field to Slack message

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?

Sign the Assembly with a Strong Name

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.

Application exit before slack log is "slacked"

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 ;-)

Support custom timestamp attachment format

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?

Missing license file

I would like to use this project but I need to know under which license I can use it.

Stacktrace field with too long message causes incorrect display

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).

Allow one channel per log level

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.

Feature Request: Filtering Logs based on Properties

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

Slack webhook only working in dotnet core

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

Sink not writing to Slack

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?

PeriodicBatchingSink Duplicates Messages on Failure

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?

Enhancement: Allow option to add custom attachments

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.

MinimumLogEventLevel is ignored

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

Sink not working in .NET Framework 4.5.2

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();

Add support for outputTemplate message formatting

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

Does not force flush on disposal

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.