{"id":37056494,"url":"https://github.com/hokagedami/serilog-stacktrace-enricher","last_synced_at":"2026-01-14T06:22:57.555Z","repository":{"id":307001486,"uuid":"1028010783","full_name":"hokagedami/serilog-stacktrace-enricher","owner":"hokagedami","description":"A Serilog enricher that adds call stack information to log events in an exception-like format. Displays call stacks as: Method:Line --\u003e Method:Line --\u003e Method:Line for intuitive debugging and tracing.","archived":false,"fork":false,"pushed_at":"2025-08-27T12:58:28.000Z","size":743,"stargazers_count":275,"open_issues_count":13,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-05T05:14:59.726Z","etag":null,"topics":["callstack","csharp","debugging","diagnostics","dotnet","enricher","exception-format","logging","serilog","stack-trace"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hokagedami.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-28T22:14:36.000Z","updated_at":"2025-12-01T17:03:43.000Z","dependencies_parsed_at":"2025-07-28T23:26:18.161Z","dependency_job_id":"29a96140-0214-4511-9abe-192661cab0bf","html_url":"https://github.com/hokagedami/serilog-stacktrace-enricher","commit_stats":null,"previous_names":["hokagedami/serilog-stacktrace-enricher"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/hokagedami/serilog-stacktrace-enricher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hokagedami%2Fserilog-stacktrace-enricher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hokagedami%2Fserilog-stacktrace-enricher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hokagedami%2Fserilog-stacktrace-enricher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hokagedami%2Fserilog-stacktrace-enricher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hokagedami","download_url":"https://codeload.github.com/hokagedami/serilog-stacktrace-enricher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hokagedami%2Fserilog-stacktrace-enricher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["callstack","csharp","debugging","diagnostics","dotnet","enricher","exception-format","logging","serilog","stack-trace"],"created_at":"2026-01-14T06:22:57.092Z","updated_at":"2026-01-14T06:22:57.550Z","avatar_url":"https://github.com/hokagedami.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serilog.Enrichers.CallStack\n\nA Serilog enricher that adds call stack information to log events in an exception-like format. This enricher helps with debugging and tracing by providing detailed context about where log events originated, displaying the call stack in an intuitive format similar to exception stack traces.\n\n_Last updated: August 2025_\n\n## Features\n\n- **Exception-like Format**: Display call stack in familiar format: `Method:Line --\u003e Method:Line --\u003e Method:Line`\n- **Single Property**: Consolidates call stack into one `CallStack` property for cleaner logs\n- **Configurable Depth**: Control the number of frames to include (default: 5)\n- **Method Parameters**: Optional parameter information in method names\n- **Type Information**: Include declaring type names with optional namespace\n- **Line Numbers**: Precise source code line numbers for exact location tracking\n- **Backward Compatibility**: Legacy format with individual properties still available\n- **Frame Filtering**: Skip specific namespaces or types when walking the call stack\n- **Exception Handling**: Configurable exception handling to prevent logging failures\n- **Flexible Configuration**: Extensive configuration options for customization\n\n## Installation\n\n```bash\ndotnet add package Serilog.Enrichers.CallStack\n```\n\n## Quick Start\n\n### Basic Usage\n\n```csharp\nusing Serilog;\nusing Serilog.Enrichers.CallStack;\n\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack()\n    .WriteTo.Console()\n    .CreateLogger();\n\nlogger.Information(\"Hello, world!\");\n```\n\nThis will produce log output similar to:\n```\n[15:30:45 INF] Hello, world! {CallStack=\"Program.Main:12 --\u003e Program.\u003cMain\u003e$:8\"}\n```\n\n### Exception-like Format (Default)\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack(config =\u003e config\n        .WithCallStackFormat(useExceptionLikeFormat: true, maxFrames: 3)\n        .WithMethodParameters(includeParameters: true)\n        .WithFullNames(fullTypeName: false)\n        .SkipNamespace(\"System\")\n        .SkipNamespace(\"Microsoft\"))\n    .WriteTo.Console(outputTemplate: \n        \"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} | {CallStack}{NewLine}{Exception}\")\n    .CreateLogger();\n```\n\n### Legacy Format\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack(config =\u003e config\n        .WithCallStackFormat(useExceptionLikeFormat: false) // Use individual properties\n        .WithIncludes(methodName: true, typeName: true, fileName: true, lineNumber: true)\n        .WithFullNames(fullTypeName: true)\n        .WithMethodParameters(includeParameters: true))\n    .WriteTo.Console()\n    .CreateLogger();\n```\n\n## Configuration Options\n\n### Call Stack Format\n\nChoose between the new exception-like format or legacy individual properties:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithCallStackFormat(\n        useExceptionLikeFormat: true,    // Default: true\n        maxFrames: 5,                    // Default: 5, -1 for unlimited\n        callStackPropertyName: \"CallStack\"); // Default: \"CallStack\"\n```\n\n**Exception-like Format Output:**\n```\nCallStack: \"UserService.ProcessUser:45 --\u003e UserController.CreateUser:23 --\u003e Program.Main:12\"\n```\n\n**Legacy Format Output:**\n```\nMethodName: \"ProcessUser\", TypeName: \"UserService\", FileName: \"UserService.cs\", LineNumber: 45\n```\n\n### Include/Exclude Information\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithIncludes(\n        methodName: true,      // Include method names\n        typeName: true,        // Include type names\n        fileName: true,        // Include file names\n        lineNumber: true,      // Include line numbers\n        columnNumber: false,   // Include column numbers\n        assemblyName: false);  // Include assembly names\n```\n\n### Property Names\n\nCustomize the property names used in log events:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithPropertyNames(\n        methodName: \"Method\",\n        typeName: \"Class\",\n        fileName: \"File\",\n        lineNumber: \"Line\",\n        columnNumber: \"Column\",\n        assemblyName: \"Assembly\");\n```\n\n### Full vs. Short Names\n\nControl whether to use full names (with namespaces/paths) or short names:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithFullNames(\n        fullTypeName: true,        // Use \"MyApp.Services.UserService\" vs \"UserService\"\n        fullFileName: true,        // Use full path vs just filename\n        fullParameterTypes: true); // Use full type names in parameters\n```\n\n### Method Parameters\n\nInclude method parameter information in the method name:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithMethodParameters(\n        includeParameters: true,\n        useFullParameterTypes: false);\n\n// Results in: \"ProcessUser(String name, Int32 id)\" instead of just \"ProcessUser\"\n```\n\n### Skip Frames\n\nSkip specific namespaces or types when walking the call stack:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .SkipNamespace(\"System\")\n    .SkipNamespace(\"Microsoft\")\n    .SkipNamespace(\"Serilog\")\n    .SkipType(\"MyApp.Infrastructure.LoggingWrapper\");\n```\n\n### Frame Offset\n\nChoose which frame in the call stack to capture:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithFrameOffset(1); // Skip 1 frame up the call stack\n```\n\n### Exception Handling\n\nConfigure how exceptions during enrichment are handled:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithExceptionHandling(\n        suppress: true,  // Don't throw exceptions\n        onException: ex =\u003e Console.WriteLine($\"Enricher error: {ex.Message}\"));\n```\n\n## Quick Start Examples\n\nFor most common scenarios, use the convenient preset methods:\n\n### Production Setup (Minimal Overhead)\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStackForProduction(maxFrames: 5)\n    .WriteTo.Console()\n    .CreateLogger();\n\n// Optimized for performance:\n// - Exception-like format with 5 frames max\n// - Method and type names only (no file/line info)\n// - Skips System/Microsoft namespaces  \n// - Suppresses enricher exceptions\n```\n\n### Development Setup (Full Details)  \n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStackForDevelopment(maxFrames: 15)\n    .WriteTo.Console()\n    .CreateLogger();\n\n// Comprehensive debugging info:\n// - Exception-like format with 15 frames max\n// - Includes file names and line numbers\n// - Shows method parameters\n// - Throws exceptions for troubleshooting\n```\n\n## Advanced Configuration Examples\n\n### Minimal Configuration\n\nFor production environments where you want minimal overhead:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithIncludes(\n        methodName: true,\n        typeName: true,\n        fileName: false,      // Skip file names to reduce overhead\n        lineNumber: false,    // Skip line numbers\n        columnNumber: false,\n        assemblyName: false)\n    .WithFullNames(fullTypeName: false); // Use short type names\n```\n\n### Development Configuration\n\nFor development environments where you want maximum detail:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithIncludes(\n        methodName: true,\n        typeName: true,\n        fileName: true,\n        lineNumber: true,\n        columnNumber: true,\n        assemblyName: true)\n    .WithFullNames(\n        fullTypeName: true,\n        fullFileName: true,\n        fullParameterTypes: true)\n    .WithMethodParameters(includeParameters: true)\n    .WithExceptionHandling(suppress: false); // Throw exceptions for debugging\n```\n\n### Filtering Configuration\n\nSkip common framework types and focus on application code:\n\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .SkipNamespace(\"System\")\n    .SkipNamespace(\"Microsoft\")\n    .SkipNamespace(\"Serilog\")\n    .SkipNamespace(\"Newtonsoft\")\n    .SkipType(\"MyApp.Infrastructure.LoggingService\")\n    .WithFrameOffset(0);\n```\n\n## Integration with Different Sinks\n\n### Console Output with Exception-like Format\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack()\n    .WriteTo.Console(outputTemplate: \n        \"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} | Call Stack: {CallStack}{NewLine}{Exception}\")\n    .CreateLogger();\n```\n\n### Console Output with Legacy Format\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack(config =\u003e config.WithCallStackFormat(useExceptionLikeFormat: false))\n    .WriteTo.Console(outputTemplate: \n        \"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} \" +\n        \"({TypeName}.{MethodName} in {FileName}:{LineNumber}){NewLine}{Exception}\")\n    .CreateLogger();\n```\n\n### JSON Output (for structured logging)\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack()\n    .WriteTo.File(new JsonFormatter(), \"log.json\")\n    .CreateLogger();\n```\n\n### Seq Integration\n\n```csharp\nvar logger = new LoggerConfiguration()\n    .Enrich.WithCallStack()\n    .WriteTo.Seq(\"http://localhost:5341\")\n    .CreateLogger();\n```\n\n## Performance Considerations\n\n### Key Performance Factors\n\n- **Debug vs Release**: Call stack information is more accurate in Debug builds\n- **File/Line Info**: Including file names and line numbers requires debug symbols\n- **Method Parameters**: Including parameter information adds overhead\n- **Frame Skipping**: Use skip configurations to avoid walking unnecessary frames  \n- **Exception Handling**: Enable exception suppression in production\n\n### Optimization Strategies\n\n**1. Limit Frame Depth**\n```csharp\n.Enrich.WithCallStack(config =\u003e config\n    .WithCallStackFormat(maxFrames: 10)) // Reduce from default unlimited\n```\n\n**2. Skip Framework Namespaces**\n```csharp\n.Enrich.WithCallStack(config =\u003e config\n    .SkipNamespace(\"System\")\n    .SkipNamespace(\"Microsoft.AspNetCore\")\n    .SkipNamespace(\"Microsoft.Extensions\"))\n```\n\n**3. Selective Property Inclusion**\n```csharp\n// For production - minimal overhead\n.Enrich.WithCallStack(config =\u003e config\n    .WithIncludes(methodName: true, typeName: true, fileName: false, lineNumber: false))\n\n// For development - full details\n.Enrich.WithCallStack(config =\u003e config\n    .WithIncludes(methodName: true, typeName: true, fileName: true, lineNumber: true))\n```\n\n**4. Configuration Validation**\n```csharp\nvar config = new CallStackEnricherConfiguration()\n    .WithCallStackFormat(maxFrames: 150);\n\n// Check for performance warnings\nif (!config.Validate(warning =\u003e Console.WriteLine($\"Warning: {warning}\")))\n{\n    // Handle validation errors\n}\n```\n\n## Debug Symbols\n\nFor file names and line numbers to work properly, ensure your application is built with debug symbols:\n\n```xml\n\u003cPropertyGroup\u003e\n  \u003cDebugType\u003eportable\u003c/DebugType\u003e\n  \u003cDebugSymbols\u003etrue\u003c/DebugSymbols\u003e\n\u003c/PropertyGroup\u003e\n```\n\n## Example Output\n\n### Exception-like Format (Default)\n\nWith the new exception-like format, log events include a single CallStack property:\n\n```json\n{\n  \"@t\": \"2025-07-29T00:30:45.123Z\",\n  \"@l\": \"Information\",\n  \"@m\": \"Processing user request\",\n  \"CallStack\": \"UserService.ProcessRequest(String userId, UserRequest request):45 --\u003e UserController.CreateUser:23 --\u003e Program.Main:12\"\n}\n```\n\n### Legacy Format\n\nWhen using legacy format (`useExceptionLikeFormat: false`), individual properties are included:\n\n```json\n{\n  \"@t\": \"2025-07-29T00:30:45.123Z\",\n  \"@l\": \"Information\",\n  \"@m\": \"Processing user request\",\n  \"MethodName\": \"ProcessRequest(String userId, UserRequest request)\",\n  \"TypeName\": \"MyApp.Services.UserService\",\n  \"FileName\": \"UserService.cs\",\n  \"LineNumber\": 45,\n  \"ColumnNumber\": 12,\n  \"AssemblyName\": \"MyApp.Services\"\n}\n```\n\n## Best Practices\n\n1. **Use exception-like format for readability**: The default format provides intuitive call stack traces\n2. **Limit frame depth in production**: Use `maxFrames` to control overhead (default: 5 frames)\n3. **Skip framework namespaces**: Focus on your application code by skipping system namespaces\n4. **Consider performance impact**: Call stack walking has overhead, tune `maxFrames` accordingly\n5. **Enable exception suppression in production**: Prevent logging failures from breaking your application\n6. **Use structured logging sinks**: JSON-based sinks work best with the call stack properties\n7. **Choose appropriate format**: Exception-like for debugging, legacy for detailed property access\n\n## Compatibility\n\n- **.NET Standard 2.0+**: Compatible with .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+\n- **Serilog 3.0+**: Requires Serilog version 3.0 or higher\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Contributing\n\nWe welcome contributions to improve Serilog.Enrichers.CallStack! Here's how you can help:\n\n### How to Contribute\n\n1. **Fork the repository** and create your branch from `main`\n2. **Make your changes** with appropriate test coverage\n3. **Ensure all tests pass** and the code follows existing patterns\n4. **Update documentation** if you're changing functionality\n5. **Submit a pull request** with a clear description of changes\n\n### Development Guidelines\n\n- Follow existing code style and conventions\n- Add unit tests for new functionality\n- Update the README for user-facing changes\n- Keep commits focused and atomic\n- Write clear, descriptive commit messages\n\n### Reporting Issues\n\nIf you find a bug or have a feature request, please open an issue with:\n- A clear title and description\n- Steps to reproduce (for bugs)\n- Expected vs actual behavior\n- Your environment details (OS, .NET version, etc.)\n\n### Questions or Discussions\n\nFor questions or discussions about the enricher, please open a GitHub discussion or issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhokagedami%2Fserilog-stacktrace-enricher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhokagedami%2Fserilog-stacktrace-enricher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhokagedami%2Fserilog-stacktrace-enricher/lists"}