{"action":"created","issue":{"url":"https://api.github.com/repos/serilog/serilog/issues/773","repository_url":"https://api.github.com/repos/serilog/serilog","labels_url":"https://api.github.com/repos/serilog/serilog/issues/773/labels{/name}","comments_url":"https://api.github.com/repos/serilog/serilog/issues/773/comments","events_url":"https://api.github.com/repos/serilog/serilog/issues/773/events","html_url":"https://github.com/serilog/serilog/issues/773","id":160106355,"number":773,"title":"Export/Import contents of LogContext","user":{"login":"IanYates","id":1314477,"avatar_url":"https://avatars.githubusercontent.com/u/1314477?v=3","gravatar_id":"","url":"https://api.github.com/users/IanYates","html_url":"https://github.com/IanYates","followers_url":"https://api.github.com/users/IanYates/followers","following_url":"https://api.github.com/users/IanYates/following{/other_user}","gists_url":"https://api.github.com/users/IanYates/gists{/gist_id}","starred_url":"https://api.github.com/users/IanYates/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IanYates/subscriptions","organizations_url":"https://api.github.com/users/IanYates/orgs","repos_url":"https://api.github.com/users/IanYates/repos","events_url":"https://api.github.com/users/IanYates/events{/privacy}","received_events_url":"https://api.github.com/users/IanYates/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-06-14T06:28:08Z","updated_at":"2016-06-14T23:23:43Z","closed_at":null,"body":"Hi,\r\n\r\nFollowing on from #529 , I've got my own wrapped up timings methods where, if the Action or Func<Task> takes longer than expected I log out messages repeatedly to Seq via Serilog.  It's helpful to see how much activity is spent waiting on some shared mutex and I can track back to the source (although my Seq filtering skills in 3.x are not well exercised yet).\r\n\r\nThese timing messages are done via a timer - on its first trigger it'll log a warning and subsequent triggers it bumps things up to error.  This is different from simply logging start & finish + duration since I'd like insight into some process that's longer-running than expected whilst it's still running.  (example: it came in handy when I accidentally had an async void `Action<T>`, rather than an async task `Func<T,Task>`, lambda leading to some weird deadlock behaviour).\r\n\r\nUnfortunately this all happens on a background timer thread so the contents of LogContext that I'd like to include is effectively lost.\r\n\r\nA suggested LogContext API in from #529 was\r\n```\r\nvar parent = LogContext.Export();\r\n\r\nTask.Run(() =>\r\n{\r\n   LogContext.Import(parent);\r\n\r\n   Log.Information(\"Here 'tis\");\r\n});\r\n```\r\n\r\nIs this still a good idea?  Would a PR along these lines be accepted, or is something like it already possible today and I just haven't noticed?"},"comment":{"url":"https://api.github.com/repos/serilog/serilog/issues/comments/226046190","html_url":"https://github.com/serilog/serilog/issues/773#issuecomment-226046190","issue_url":"https://api.github.com/repos/serilog/serilog/issues/773","id":226046190,"user":{"login":"nblumhardt","id":342712,"avatar_url":"https://avatars.githubusercontent.com/u/342712?v=3","gravatar_id":"","url":"https://api.github.com/users/nblumhardt","html_url":"https://github.com/nblumhardt","followers_url":"https://api.github.com/users/nblumhardt/followers","following_url":"https://api.github.com/users/nblumhardt/following{/other_user}","gists_url":"https://api.github.com/users/nblumhardt/gists{/gist_id}","starred_url":"https://api.github.com/users/nblumhardt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nblumhardt/subscriptions","organizations_url":"https://api.github.com/users/nblumhardt/orgs","repos_url":"https://api.github.com/users/nblumhardt/repos","events_url":"https://api.github.com/users/nblumhardt/events{/privacy}","received_events_url":"https://api.github.com/users/nblumhardt/received_events","type":"User","site_admin":false},"created_at":"2016-06-14T23:23:43Z","updated_at":"2016-06-14T23:23:43Z","body":"Hi Ian - interesting scenario.\r\n\r\nExport/Import seems like it would cover this, but since `LogContext` might already be active in the destination task (not in your example, but generally), the import method would need to be more like a \"push\", adding to the destination context for a time until it is popped off again.\r\n\r\nI'm not 100% certain it'd all fall out nicely, but for the sake of discussion what do you make of:\r\n\r\n```csharp\r\nvar parent = LogContext.Clone();\r\n\r\nTask.Run(() =>\r\n{\r\n   using (LogContext.Push(parent))\r\n   {\r\n      Log.Information(\"Here 'tis\");\r\n   }\r\n});\r\n```\r\n\r\nIn this case, `Clone()` would return `ILogEventEnricher`, and `Push(ILogEventEnricher)` would be a new method eventually replacing the awkwardly-named `PushProperties()`. Including `Push(ILogEventEnricher)` and `Push(IEnumerable<ILogEventEnricher>)` or similar in the PR while `[Obsolete]`ing `PushProperties()` would be a nice tidy-up.\r\n\r\n"}}
{"actor":{"display_login":"nblumhardt"}}