Yan Cui
I help clients go faster for less using serverless technologies.
This article is brought to you by
Don’t reinvent the patterns. Catalyst gives you consistent APIs for messaging, data, and workflow with key microservice patterns like circuit-breakers and retries for free.
Here at Gamesys social team, we’re rethinking our current approach to logging in general, from both server and client’s perspective. Having looked at many different alternatives (it was a little hard to imagine how crowded a space log aggregation and visualization is..) one of the services which we have decided to experiment with is Sentry.
Sentry is a fairly simple service, with an easy to use API and straight forward to integrate with, especially if you already have a client library (the Sentry doc refers to them them as Ravens) for your language of choice. On the .Net side of things, you have a little library called SharpRaven.
As for integration, using custom log4net appender such as this one is obviously a good way to go, but you still need to implement the try-catch-log pattern everywhere though, unless you’re happy for these exceptions to bubble all the way up to the app domain and catch them there. And when I see implementation patterns I see opportunities to automate them with PostSharp!
C# custom attributes
If you grab the SharpRaven-Contrib package from Nuget you’ll have access to a pair of custom attributes – RavenLogException and RavenLogExecutionTimeAttribute – when you open the SharpRaven namespace. For example,
The attributes does what they say on the tin, RavenLogException captures and logs exception information as errors to Sentry whilst RavenLogExecutionTime monitors execution time of your methods and logs any method execution that took longer than your given threshold as warnings to Sentry.
For F# however, whilst the attributes would still work for methods, chances are you will be spending most of your time working and composing functions instead and these attributes won’t help you there. So for F# I decided to do something slightly different.
F# workflows
Thankfully, in F#, we have computation expressions* (aka workflows) which already power language features such as async workflows and sequence comprehensions.
Using the workflows defined in the SharpRaven-ContribFs package you can create blocks of code where:
- any unhandled exceptions are logged as Error in Sentry
- if the block of code takes longer than the specified threshold to execute, it’ll be logged as a warning in Sentry
and your code remains unchanged, you simply wrap them in { }:
Of course, you can also just create wrapper functions to achieve the same results, but I find that using workflows in this case makes for more readable code. Another good alternative is to use a Maybe monad, which I won’t go into too much detail here as Scott Wlaschin has a great explanation for this already.
As always, the source code for both libraries are available on github, and if you find any issues feel free to report them via the issues page.
* if you’re interested in learning more about computation expressions, I highly recommend Scott Wlaschin’s series on his F# for Fun and Profit blog, it’s by far the most comprehensive and easy to understand set of articles I have seen.
Links
- SharpRaven client Nuget package
- C# custom attributes Nuget package
- F# workflows Nuget package
- Project homepage
- C# example
- F# example
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.
Pingback: F# Weekly #26, 2014 | Sergey Tihon's Blog
Pingback: Introduce raven_dart, a Dart client for Sentry | theburningmonk.com
Pingback: Year in Review, 2014 | theburningmonk.com