Serilog | How to control logging level based upon a custom filter - serilog

I would like to be able to dynamically control the logging level for Serilog based upon a custom query. At minimum, I would like to be able to filter log messages by the start of their SourceContext (ie, the namespace/full class name) - this could be optimized with a compiled regex statement/state machine to handle the matching.
Ideally, in addition to the above, I could create SourceContext filters that are applicable to only certain users - such as via a UserId field on the event - that would take priority over filters that don't have a UserId specified.
I would like to be able to dynamically modify the set of such filters via an Admin website, allowing myself or other admins to increase/decrease the verbosity level of specific parts of the code and for specific users as the need arises.
I was wondering if anyone here knows the best way to go about implementing such a feature with Serilog? I've googled this, but I haven't found any filtering capabilities out of the box for Serilog that look like they'd be up to this task. In which case, I might go about it by means of an intermediate, in-process Sink.

I found an answer to a related but distinct issue that looks like a good solution: How to change the LogLevel of specific log events in Serilog?_
It looks like Serilog does provide a mechanism for wrapping sinks in intermediate sinks, and it shouldn't be too difficult to apply the filtration logic I'm seeking by doing so.

Related

CQRS, event sourcing and a translated application

I am working on an application (CQRS + event sourcing) that should support multiple user languages. The user will have the ability to translate some of his input different languages. E.g. some labels or descriptions can be given in Dutch and/or English. Depending on the language preferences of the user, the application should show the correct translation.
I suspect the read model plays a big role in this process.
I was thinking of creating events like ItemDescriptionTranslated, telling 'The description of item X was translated to language Y as Z'.
I would think that the aggregate can safely ignore this kind of events, and that only the read models should do something with this information.
Does this make sense? Does any of you have experience with CQRS/ES in a translated application? Any hints are greatly appreciated.
Of cource you can use event sourcing. You can code aggregate's build funcs to ignore ItemDescriptionTranslated event.
The main question is - if you really need event sourcing in this part of application. For example you can build authorization using both ways - es or not. If you want to log all users' login and auth, you prefer ES. But if you want login only, without any analysis - i suggest not to use es.
So, do you want to collect some additional info about translating? When, who, maybe check some statistics about corrections by different authors and so on.

Check Site URL which fills data in Report Suite in SiteCatalyst (Omniture)

This question may seems odd but we have a slight mixup within our Report Suites on Omniture (SiteCatalyst). Multiple Report Suites are generating analytics and it's hard for us to find which site URL is constituting the results.
Hence my question is, is there any way we can find which Site is filling data within a certain Report Suite.
Through this following JS, I am able to find which "report suite" is being used by a certain site though:-
javascript:void(window.open("","dp_debugger","width=600,height=600,location=0,menubar=0,status=1,toolbar=0,resizable=1,scrollbars=1").document.write("<script language=\"JavaScript\" id=dbg src=\"https://www.adobetag.com/d1/digitalpulsedebugger/live/DPD.js\"></"+"script>"));
But I am hoping to find the other way around that where Report Suite gets its data from within the SiteCatalyst admin.
Any assistance?
Thanks
Adobe Analytics (formerly SiteCatalyst) does not have anything native or built in to globally look at all data coming to see which page/site is sending data to which report suite. However, you can contact Adobe ClientCare and request raw hit logs for a date range, and you can parse those logs yourself, if you really want.
Alternatively, if you have Data Warehouse access, you can export urls and domains from there for a given date range. You can only select one report suite at a time but that's also better than nothing, if you really need the historical data now.
Another alternative is if your sites are NOT currently setting s.pageName, then you may be in some measure of luck for your historical data. The pages report is popped from s.pageName value. If you do not set that variable, it will default to the URL of the web page that made the request. So, at a minimum you will be able to see your URLs in that report right now, so that should help you out. And if you define "site" as equivalent of "domain" (location.hostname) you can also setup a classification level for pages for domain and then use the Classification Rule Builder and a regular expression to pop the classification with the domain, which will give you some aggregated numbers.
Some suggestions moving forward...
I good strategy moving forward is to have all of your sites report to a global report suite. Then, you can have each site also send data to a site level report suite (warning: make sure you have enough server calls in your contract to cover this, since AA does not have unlimited server calls). Alternatively, you can stick with one global report suite and setup segments for each site. Another alternative is to create a rollup report suite to have all data from your other report suites to also go to. Rollup report suites do not have as many features as standard report suites, but for basic things such as pages, page views, it works.
The overall point though is that one way or the other, you should have all of your data go into one report suite as the first step.
Then, you should also assign a few custom variables to be output on the pages of all your sites. These are the 4 main things I always try to include in an implementation to make it easier to find out which sites/pages are reporting to what.
A custom variable to identify the site. Some people use s.server for this. However, you may also want to pop a prop or eVar with the value as well, depending on how you'd like to be able to break data down. The big question here is: How do you define "site" ? I have seen it defined many different ways.
If you do NOT define "site" as domain (e.g. location.hostname) then I suggest you pop a prop and eVar with the domain, because AA does not have a native report for this. But if you do, then you can skip this, since it's same thing as point #1
A custom prop and eVar with the report suites(s). Unless you have a super old version of legacy code, just set it with s.sa(). This will ensure you get the final report suite(s), in case you happen to use a version that uses Dynamic Account variables (e.g. s.dynamicAccountList).
If you set s.pageName with a custom value, then I suggest you pop a prop and eVar with the URL. Tip: to save on request url length to AA, you can use dynamic variable syntax to copy the g parameter already in a given AA request. For example (assuming you don't have code that changes the dynamic variable prefix): s.prop1='D=g'; Or, you can pop this with a processing rule if you have the access.
you can normally find this sort of information in the Site Content-> Servers report. There will be information in there the indicates what sites are sending in the hits. Your milage may vary based on the actual tagging implementation, it is not common for anyone to explicitly set the server, so the implicit value is the domain the hit is coming in from.
Thanks C.

How to add multiple *.sitemap files to mvcsitemapprovider during session start

I want to associate multiple sitemaps to mvcsitemapprovider during session_start event as sitemaps names and locations are retrieved based upon the type of client/user. But, according to documents related to mvcsitemapprovider, all *.sitemaps are getting associated to mvcsitemapprovider during application start. Is there any way, I can provide this functionality using this control?
There is no built-in per session functionality, but you could implement your own ICacheProvider to handle this requirement. Also see MvcSiteMapProvider 4.0 - Extending the Cache and Multiple SiteMaps in One Application for more guidance.
Do note that the primary reason this doesn't exist out of the box is because it would be extremely memory intensive and would not scale to very many users. Unless your navigation is completely different per user, I wouldn't recommend using this approach. A better alternative is to use the preservedRouteParameters approach to force some route values to match any value (in your case userid or clientid), and then use ISiteMapNodeVisibilityProvider, SiteMapTitleAttribute, and/or manual updating of SiteMapNode properties per request to control the visibility of the node.
Please see my open question here and explain to me why you would want to do this on GitHub, as it renders most of the features useless: https://github.com/maartenba/MvcSiteMapProvider/issues/16#issuecomment-22229604

Extending role based security to allow roles for a specific entity

I've used FluentSecurity in another MVC application and its great, provides a slick implementation.
I now have a requirement to offer application wide roles, plus also provide additional permission control over individiual entities.
My application manages particular locations and a user may have permissions to perform actions at one or more locations, each location has a unique id. I'll need to check a user has a particular role for the location id (effectively adding another dimension to roles). I've got my schema mapped out, along with my repo/service layers.
I was wondering if someone has tackled this type of problem before and whether its worth me trying to solve with FluentSecurity or if I should validate the user has the role required for the location on each GET/POST request (controller or service layer).
I'm getting to achieve this in FluentSecurity I'll have to roll my own policy and capture the location id from the RequestContext.RouteData.
I haven't done exactly what you need to do, but creating a custom policy in FluentSecurity that handles your scenario should not be hard at all. If you feel it is, please let me know and I will have to fix that.
You can find more information on how to create custom policies here:
https://github.com/kristofferahl/FluentSecurity/wiki/Custom-policies
It sounds to me like you might want to split it into two custom policies. You then apply your custom policies like this:
configuration.For<SomeController>()
.AddPolicy<CustomPolicy1>()
.AddPolicy<CustomPolicy2>();

What is a good Rails logging solution?

I am looking for a solution that will allow me to do advanced logging:
Unlimited log size
Ability to filter by priorities (debug/info/error)
Ability to filter by models/custom- tag
Ability to filter by user-sessions (see only errors for a specific session)
Should be able to work on Heroku
*Optional: Set rules to email/sms on certain high-priority errors
Either a tool that works with files and can easily diesct them, or a DB backed log storage.
Any suggestions are most welcome
Try Log4r first; if it doesn't do exactly what you need, it's pretty tweakable.

Resources