https://github.com/byndyusoft/byndyusoft.logging
Структурные логи в json формате
https://github.com/byndyusoft/byndyusoft.logging
byndyusoft csharp logging
Last synced: 9 months ago
JSON representation
Структурные логи в json формате
- Host: GitHub
- URL: https://github.com/byndyusoft/byndyusoft.logging
- Owner: Byndyusoft
- License: mit
- Created: 2021-04-07T09:39:43.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2024-05-08T07:06:28.000Z (about 2 years ago)
- Last Synced: 2025-05-30T14:21:44.942Z (about 1 year ago)
- Topics: byndyusoft, csharp, logging
- Language: C#
- Homepage:
- Size: 150 KB
- Stars: 0
- Watchers: 3
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Byndyusoft.Logging [](https://www.nuget.org/packages/Byndyusoft.Logging/) [](https://www.nuget.org/packages/Byndyusoft.Logging/)
Структурные логи в json формате.
Библиотека является набором пресетов для Serilog, которые позволяют добавлять поддержку логирования в несколько строк.
```
using Byndyusoft.Logging.Configuration;
using Serilog;
...
Host.CreateDefaultBuilder(args)
.UseSerilog((context, configuration) => configuration
.UseDefaultSettings(context.Configuration, "Sample project")
)
```
В результате такого подключения будут добавлено логирование в стандартный вывод логов в формате json. Каждый вывод в лог производится с новой строки и занимает 1 строку.
Например, для тестового вывода будет, будет получен следущей лог:
```
var values = new[] {"value1", "value2"};
logger.LogInformation("запрошены {@Values}", (object)values);
Вывод (отформатированный):
{
"Timestamp": "2021-04-09T13:12:58.2633978Z",
"Message": "запрошены [\"value1\", \"value2\"]",
"MessageTemplateHash": "05114bc8",
"Level": "Information",
"Properties": {
"Values": [
"value1",
"value2"
]
}
}
```
Где:
- `Timestamp` — время в utc в которое создана запись лога
- `Message` — залогированное сообщение с подставленными параметрами
- `MessageTemplateHash` — хэш шаблона сообщения, который не зависит от параметров
- `Level` — уровень лога
- `Properties.*` — все остальные свойства сообщения
- `Values` — параметры сообщения
Кроме того `Properties.*` обогащается полями добавленными в контекст лога. Т.е. если вызывать `logger.LogInformation("запрошены {@Values}", (object)values)` из метода контроллера, то в `Properties` добавятся следующие поля, которые добавляет инфраструктура asp.net
```
"SourceContext": "Byndyusoft.Logging.Sample.Controllers.ValuesController",
"ActionId": "21eb782a-3717-4616-9927-7d2a5a23c8b8",
"ActionName": "Byndyusoft.Logging.Sample.Controllers.ValuesController.Get (Byndyusoft.Logging.Sample)",
"RequestId": "0HM7RB4OJU2MI:00000001",
"RequestPath": "/api/values",
"SpanId": "|b01373be-4fffa4bff3ac61ea.",
"TraceId": "b01373be-4fffa4bff3ac61ea",
"ParentId": "",
"ConnectionId": "0HM7RB4OJU2MI",
```
В случе логирования исключения, добавляет информация об исключении (ToString()) и хэш стектрейса для поиска аналогичных исключений. Хэш считается без учёта номеров строк.
```
logger.LogError(ex, "Должен совпасть хэш ошибки")
{
"Timestamp":"2021-04-09T10:10:16.6873034Z",
"Message":"Должен совпасть хэш ошибки",
"MessageTemplateHash":"3e4763a9",
"Level":"Error",
"Exception":"System.Exception: Что-то пошло не так\r\n ---> 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",
"ExceptionHash":"533f548e",
...
}
```
# Поддержка трассировки
## OpenTracing [](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTracing/) [](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTracing/)
Сначала нужно подключить `Byndyusoft.Logging.OpenTracing`
Можно заменить значения `TraceId` и `SpanId` на полученные от OpenTracing. `ParentId` совсем удаляет.
```
.UseSerilog((context, configuration) => configuration
.UseOpenTracingTraces()
```
Можно сделать так, чтобы всё что пишется в логи, оказалось в трасах.
```
.UseSerilog((context, configuration) => configuration
.WriteToOpenTracing()
```
## OpenTelemetry [](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry/) [](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry/)
Сначала нужно подключить `Byndyusoft.Logging.OpenTelemetry`
Можно заменить значения `TraceId` и `SpanId` на полученные от OpenTelemetry. `ParentId` совсем удаляет.
```
.UseSerilog((context, configuration) => configuration
.UseOpenTelemetryTraces()
```
Можно сделать так, чтобы всё что пишется в логи, оказалось в трасах.
```
.UseSerilog((context, configuration) => configuration
.WriteToOpenTelemetry()
```
# Предусмотренные сценарии
## Как добавить вывод в файл?
```
.UseSerilog((context, configuration) => configuration
.UseFileWriterSettings()
```
В рабочей паке будут добавлены 2 файла `logs/verbose.log` и `error.log`
## Как изменить уровень логирования на проде?
Это просто Serilog. Поэтому в ваших настройках должен быть параметр `Serilog:MinimumLevel:Default` с желаемым уровнем логирования. В переменных окружения `:` нужно заменить на `__`: `Serilog__MinimumLevel__Default`.
## Мне не подходят стандартные настройки
Помните, что это всё ещё обычный Serilog. Вы можете изменить настройки так, как вам нравится. Скажем `UseDefaultSettings` представляет из себя следующей вызов:
```
return loggerConfiguration
.Enrich.FromLogContext()
.UseConsoleWriterSettings(restrictedToMinimumLevel)
.OverrideDefaultLoggers()
.ReadFrom.Configuration(configuration)
```
Можно использовать только те его части, которые подходят вашему проекту.
## Хочу положить в события трассировок только заданные мной параметры, а не весь лог (структурные события)
Если использовать стандартный способ переноса логов в события трассы, то в них будут попадать само сообщение лога, его свойства и остальные дополнительные параметры, такие как уровень логирования и контекст логирования. В трассах выглядит следующим образом:

Если требуется, чтобы в событиях трассы попадали только параметры без дублирования их в сообщении, то можно использовать структурные события. Они позволяют записать события в виде название события и его параметров.
Пример:

Чтобы заработали структурные события, нужно подключить `StructuredActivityEventBuilder`:
```
.UseSerilog((context, configuration) => configuration
.WriteToOpenTelemetry(activityEventBuilder: StructuredActivityEventBuilder.Instance)
```
После этого можно создавать структурные события с помощью логирования по конвенции или вспомогательного метода.
### Логирование структурных событий по конвенции
Для этого в логах должно быть свойство _TraceEventName_, которое будет использоваться как название события в трассе:
```
_logger.LogInformation("{TraceEventName} Parameters: Company.Name = {Company_Name}; Id = {Id}", "MethodInput", "Byndyusoft", 10);
```
В логи сообщение попадёт как обычно, а событие трассы будет содержать только два параметра: _Id_ и _Company.Name_. Имя события будет _MethodInput_. События будут выглядеть, как на картинке выше.
### Логирование структурных событий через вспомогательный метод
Чтобы явно указать на использование структурных событий, можно воспользоваться вспомогательным методом `LogStructuredActivityEvent`, который находится в пакете `Byndyusoft.Logging.OpenTelemetry.Abstractions`.
[](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry.Abstractions/) [](https://www.nuget.org/packages/Byndyusoft.Logging.OpenTelemetry.Abstractions/)
Чтобы создать событие трассировки, аналогичное картинке выше, нужно написать следующее:
```
var eventItems = new[]
{
new StructuredActivityEventItem("Id", 10),
new StructuredActivityEventItem("Company.Name", "Byndyusoft")
};
_logger.LogStructuredActivityEvent("MethodInput", eventItems);
```
Пример выше полностью аналогичен коду логирования по конвенции:
```
_logger.LogInformation("Structured Event {TraceEventName} Properties: Id = {Id}; Company.Name = {Company_Name}; ", "MethodInput", 10, "Byndyusoft");
```
По умолчанию структурные события попадают в логи с уровнем _Information_.
# Обогащение дополнительными полями
Для обогащения информацией о параметрах окружения с наименованием BUILD_*, именем сервиса и версией сервиса можно воспользоваться библиотекой [Byndyusoft.Telemetry.Logging.Serilog](https://www.nuget.org/packages/Byndyusoft.Telemetry.Logging.Serilog). Документация - [тут](https://github.com/Byndyusoft/Byndyusoft.Telemetry/blob/master/README.md).