{"id":23721250,"url":"https://github.com/byndyusoft/byndyusoft.logging","last_synced_at":"2025-09-20T07:20:05.936Z","repository":{"id":44447866,"uuid":"355489500","full_name":"Byndyusoft/Byndyusoft.Logging","owner":"Byndyusoft","description":"Структурные логи в json формате","archived":false,"fork":false,"pushed_at":"2024-05-08T07:06:28.000Z","size":154,"stargazers_count":0,"open_issues_count":5,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-30T14:21:44.942Z","etag":null,"topics":["byndyusoft","csharp","logging"],"latest_commit_sha":null,"homepage":"","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/Byndyusoft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2021-04-07T09:39:43.000Z","updated_at":"2024-05-08T07:04:56.000Z","dependencies_parsed_at":"2023-12-25T07:23:13.807Z","dependency_job_id":"21d57a14-b06e-4795-bd3d-7624df7cc6bf","html_url":"https://github.com/Byndyusoft/Byndyusoft.Logging","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2FByndyusoft.Logging","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2FByndyusoft.Logging/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2FByndyusoft.Logging/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2FByndyusoft.Logging/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Byndyusoft","download_url":"https://codeload.github.com/Byndyusoft/Byndyusoft.Logging/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byndyusoft%2FByndyusoft.Logging/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259080945,"owners_count":22802396,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["byndyusoft","csharp","logging"],"created_at":"2024-12-30T22:18:19.410Z","updated_at":"2025-09-20T07:20:00.804Z","avatar_url":"https://github.com/Byndyusoft.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Byndyusoft.Logging [![Nuget](https://img.shields.io/nuget/v/Byndyusoft.Logging.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging/) [![Downloads](https://img.shields.io/nuget/dt/Byndyusoft.Logging.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging/)\n\nСтруктурные логи в json формате.\n\nБиблиотека является набором пресетов для Serilog, которые позволяют добавлять поддержку логирования в несколько строк.\n\n```\nusing Byndyusoft.Logging.Configuration;\nusing Serilog;\n\n...\n\nHost.CreateDefaultBuilder(args)\n    .UseSerilog((context, configuration) =\u003e configuration\n        .UseDefaultSettings(context.Configuration, \"Sample project\")\n    )\n\n```\n\nВ результате такого подключения будут добавлено логирование в стандартный вывод логов в формате json. Каждый вывод в лог производится с новой строки и занимает 1 строку.\n\nНапример, для тестового вывода будет, будет получен следущей лог:\n\n```\nvar values = new[] {\"value1\", \"value2\"};\nlogger.LogInformation(\"запрошены {@Values}\", (object)values);\n\nВывод (отформатированный):\n{\n\t\"Timestamp\": \"2021-04-09T13:12:58.2633978Z\",\n\t\"Message\": \"запрошены [\\\"value1\\\", \\\"value2\\\"]\",\n\t\"MessageTemplateHash\": \"05114bc8\",\n\t\"Level\": \"Information\",\n\t\"Properties\": {\n\t\t\"Values\": [\n\t\t\t\"value1\",\n\t\t\t\"value2\"\n\t\t]\n\t}\n}\n```\n\nГде:\n\n- `Timestamp` — время в utc в которое создана запись лога\n- `Message` — залогированное сообщение с подставленными параметрами\n- `MessageTemplateHash` — хэш шаблона сообщения, который не зависит от параметров\n- `Level` — уровень лога\n- `Properties.*` — все остальные свойства сообщения\n- `Values` — параметры сообщения\n\nКроме того `Properties.*` обогащается полями добавленными в контекст лога. Т.е. если вызывать `logger.LogInformation(\"запрошены {@Values}\", (object)values)` из метода контроллера, то в `Properties` добавятся следующие поля, которые добавляет инфраструктура asp.net\n\n```\n\"SourceContext\": \"Byndyusoft.Logging.Sample.Controllers.ValuesController\",\n\"ActionId\": \"21eb782a-3717-4616-9927-7d2a5a23c8b8\",\n\"ActionName\": \"Byndyusoft.Logging.Sample.Controllers.ValuesController.Get (Byndyusoft.Logging.Sample)\",\n\"RequestId\": \"0HM7RB4OJU2MI:00000001\",\n\"RequestPath\": \"/api/values\",\n\"SpanId\": \"|b01373be-4fffa4bff3ac61ea.\",\n\"TraceId\": \"b01373be-4fffa4bff3ac61ea\",\n\"ParentId\": \"\",\n\"ConnectionId\": \"0HM7RB4OJU2MI\",\n```\n\nВ случе логирования исключения, добавляет информация об исключении (ToString()) и хэш стектрейса для поиска аналогичных исключений. Хэш считается без учёта номеров строк.\n\n```\nlogger.LogError(ex, \"Должен совпасть хэш ошибки\")\n\n{\n    \"Timestamp\":\"2021-04-09T10:10:16.6873034Z\",\n    \"Message\":\"Должен совпасть хэш ошибки\",\n    \"MessageTemplateHash\":\"3e4763a9\",\n    \"Level\":\"Error\",\n    \"Exception\":\"System.Exception: Что-то пошло не так\\r\\n ---\u003e System.NotImplementedException: Скоро сделаем\\r\\n   at Byndyusoft.Logging.Sample.Controllers.ValuesController.ThrowError() in C:\\\\work\\\\reps\\\\Byndyusoft.Logging\\\\src\\\\Byndyusoft.Logging.Sample\\\\Controllers\\\\ValuesController.cs:line 58\\r\\n   at Byndyusoft.Logging.Sample.Controllers.ValuesController.ThrowErrorWithInnerError() in C:\\\\work\\\\reps\\\\Byndyusoft.Logging\\\\src\\\\Byndyusoft.Logging.Sample\\\\Controllers\\\\ValuesController.cs:line 65\\r\\n   --- End of inner exception stack trace ---\\r\\n   at Byndyusoft.Logging.Sample.Controllers.ValuesController.ThrowErrorWithInnerError() in C:\\\\work\\\\reps\\\\Byndyusoft.Logging\\\\src\\\\Byndyusoft.Logging.Sample\\\\Controllers\\\\ValuesController.cs:line 69\\r\\n   at Byndyusoft.Logging.Sample.Controllers.ValuesController.GetError() in C:\\\\work\\\\reps\\\\Byndyusoft.Logging\\\\src\\\\Byndyusoft.Logging.Sample\\\\Controllers\\\\ValuesController.cs:line 44\",\n    \"ExceptionHash\":\"533f548e\",\n    ...\n}\n\n```\n\n# Поддержка трассировки\n\n## OpenTracing [![Nuget](https://img.shields.io/nuget/v/Byndyusoft.Logging.OpenTracing.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTracing/) [![Downloads](https://img.shields.io/nuget/dt/Byndyusoft.Logging.OpenTracing.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTracing/)\n\nСначала нужно подключить `Byndyusoft.Logging.OpenTracing`\n\nМожно заменить значения `TraceId` и `SpanId` на полученные от OpenTracing. `ParentId` совсем удаляет.\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .UseOpenTracingTraces()\n```\n\n\nМожно сделать так, чтобы всё что пишется в логи, оказалось в трасах.\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .WriteToOpenTracing()\n```\n\n## OpenTelemetry [![Nuget](https://img.shields.io/nuget/v/Byndyusoft.Logging.OpenTelemetry.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry/) [![Downloads](https://img.shields.io/nuget/dt/Byndyusoft.Logging.OpenTelemetry.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry/)\n\nСначала нужно подключить `Byndyusoft.Logging.OpenTelemetry`\n\nМожно заменить значения `TraceId` и `SpanId` на полученные от OpenTelemetry. `ParentId` совсем удаляет.\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .UseOpenTelemetryTraces()\n```\n\n\nМожно сделать так, чтобы всё что пишется в логи, оказалось в трасах.\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .WriteToOpenTelemetry()\n```\n\n\n# Предусмотренные сценарии\n\n## Как добавить вывод в файл?\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .UseFileWriterSettings()\n```\n\nВ рабочей паке будут добавлены 2 файла `logs/verbose.log` и `error.log`\n\n## Как изменить уровень логирования на проде?\n\nЭто просто Serilog. Поэтому в ваших настройках должен быть параметр `Serilog:MinimumLevel:Default` с желаемым уровнем логирования. В переменных окружения `:` нужно заменить на `__`: `Serilog__MinimumLevel__Default`.\n\n## Мне не подходят стандартные настройки\n\nПомните, что это всё ещё обычный Serilog. Вы можете изменить настройки так, как вам нравится. Скажем `UseDefaultSettings` представляет из себя следующей вызов:\n\n```\nreturn loggerConfiguration\n    .Enrich.FromLogContext()\n    .UseConsoleWriterSettings(restrictedToMinimumLevel)\n    .OverrideDefaultLoggers()\n    .ReadFrom.Configuration(configuration)\n```\n\nМожно использовать только те его части, которые подходят вашему проекту.\n\n## Хочу положить в события трассировок только заданные мной параметры, а не весь лог (структурные события)\n\nЕсли использовать стандартный способ переноса логов в события трассы, то в них будут попадать само сообщение лога, его свойства и остальные дополнительные параметры, такие как уровень логирования и контекст логирования. В трассах выглядит следующим образом:\n\n![Not Structured Logs](/Not%20Structured.png?raw=true)\n\nЕсли требуется, чтобы в событиях трассы попадали только параметры без дублирования их в сообщении, то можно использовать структурные события. Они позволяют записать события в виде название события и его параметров.\nПример:\n\n![Not Structured Logs](/Structured.png?raw=true)\n\nЧтобы заработали структурные события, нужно подключить `StructuredActivityEventBuilder`:\n\n```\n.UseSerilog((context, configuration) =\u003e configuration\n    .WriteToOpenTelemetry(activityEventBuilder: StructuredActivityEventBuilder.Instance)\n```\n\nПосле этого можно создавать структурные события с помощью логирования по конвенции или вспомогательного метода.\n\n### Логирование структурных событий по конвенции\n\nДля этого в логах должно быть свойство _TraceEventName_, которое будет использоваться как название события в трассе:\n\n```\n_logger.LogInformation(\"{TraceEventName} Parameters: Company.Name = {Company_Name}; Id = {Id}\", \"MethodInput\", \"Byndyusoft\", 10);\n```\n\nВ логи сообщение попадёт как обычно, а событие трассы будет содержать только два параметра: _Id_ и _Company.Name_. Имя события будет _MethodInput_. События будут выглядеть, как на картинке выше.\n\n### Логирование структурных событий через вспомогательный метод\n\nЧтобы явно указать на использование структурных событий, можно воспользоваться вспомогательным методом `LogStructuredActivityEvent`, который находится в пакете `Byndyusoft.Logging.OpenTelemetry.Abstractions`.\n\n[![Nuget](https://img.shields.io/nuget/v/Byndyusoft.Logging.OpenTelemetry.Abstractions.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry.Abstractions/) [![Downloads](https://img.shields.io/nuget/dt/Byndyusoft.Logging.OpenTelemetry.Abstractions.svg?style=flat)](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry.Abstractions/)\n\nЧтобы создать событие трассировки, аналогичное картинке выше, нужно написать следующее:\n\n```\nvar eventItems = new[]\n{\n    new StructuredActivityEventItem(\"Id\", 10),\n    new StructuredActivityEventItem(\"Company.Name\", \"Byndyusoft\")\n};\n_logger.LogStructuredActivityEvent(\"MethodInput\", eventItems);\n```\n\nПример выше полностью аналогичен коду логирования по конвенции:\n\n```\n_logger.LogInformation(\"Structured Event {TraceEventName} Properties: Id = {Id}; Company.Name = {Company_Name}; \", \"MethodInput\", 10, \"Byndyusoft\");\n```\n\nПо умолчанию структурные события попадают в логи с уровнем _Information_.\n\n# Обогащение дополнительными полями\n\nДля обогащения информацией о параметрах окружения с наименованием BUILD_*, именем сервиса и версией сервиса можно воспользоваться библиотекой [Byndyusoft.Telemetry.Logging.Serilog](https://www.nuget.org/packages/Byndyusoft.Telemetry.Logging.Serilog). Документация - [тут](https://github.com/Byndyusoft/Byndyusoft.Telemetry/blob/master/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyndyusoft%2Fbyndyusoft.logging","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyndyusoft%2Fbyndyusoft.logging","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyndyusoft%2Fbyndyusoft.logging/lists"}