PrimaLogger 1.0.8

There is a newer version of this package available.
See the version list below for details.
dotnet add package PrimaLogger --version 1.0.8
                    
NuGet\Install-Package PrimaLogger -Version 1.0.8
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PrimaLogger" Version="1.0.8" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PrimaLogger" Version="1.0.8" />
                    
Directory.Packages.props
<PackageReference Include="PrimaLogger" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PrimaLogger --version 1.0.8
                    
#r "nuget: PrimaLogger, 1.0.8"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PrimaLogger@1.0.8
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PrimaLogger&version=1.0.8
                    
Install as a Cake Addin
#tool nuget:?package=PrimaLogger&version=1.0.8
                    
Install as a Cake Tool

PrimaLogger

Обёртка над Serilog для упрощения конфигурации логирования с поддержкой файлов, консоли и Elasticsearch.

Быстрый старт

Значения по умолчанию

ConsoleLoggerOptions

new ConsoleLoggerOptions()
Свойство Значение по умолчанию
Enabled true
MinimumLevel LogEventLevel.Information
OutputTemplate "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"

FileLoggerOptions

new FileLoggerOptions()
Свойство Значение по умолчанию
Path "logs/app-.log"
MinimumLevel LogEventLevel.Information
OutputTemplate "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
RollingInterval RollingInterval.Day
FileSizeLimitBytes 100 * 1024 * 1024 (100MB)
RollOnFileSizeLimit true
RetainedFileCountLimit 31
Shared false
Encoding Encoding.UTF8

ElasticsearchLoggerOptions

new ElasticsearchLoggerOptions()
Свойство Значение по умолчанию
Nodes [new Uri("http://localhost:9200")]
DataStreamName "logs-myapp-default"
BootstrapMethod BootstrapMethod.Failure
ApiKey null
Username null
Password null
BufferOptions null

ElasticsearchBufferOptions

new ElasticsearchBufferOptions()
Свойство Значение по умолчанию
ConcurrentConsumers 1
InboundBufferMaxSize 100000
OutboundBufferMaxSize 1000

ElasticsearchSinkOptions

new ElasticsearchSinkOptions()
Свойство Значение по умолчанию
MinimumLevel LogEventLevel.Information
Options new ElasticsearchLoggerOptions()

PrimaLoggerConfig

new PrimaLoggerConfig()
Свойство Значение по умолчанию
ApplicationName "webapp"
CustomProperties new Dictionary<string, object>() (пустой)
Console null (отключена)
File null (отключен)
ErrorFile null (отключен)
Elasticsearch null (отключен)

Важно: При new PrimaLoggerConfig() все синки отключены по умолчанию. Нужно явно настроить нужные синки или использовать presets:

// Все синки отключены
services.AddPrimaLogger(config => { });

// Включить только консоль с настройками по умолчанию
services.AddPrimaLogger(config => 
{
    config.Console = new ConsoleLoggerOptions(); // Enabled=true, Information, стандартный template
});

// Или использовать готовые presets
services.AddPrimaLogger(config => PrimaLoggerConfig.Development("MyApp"));

Минимальная конфигурация

Через код:

services.AddPrimaLogger(config =>
{
    config.Console = new ConsoleLoggerOptions();
});

Через appsettings.json:

{
  "Logging": {
    "PrimaLogger": {
      "Console": {
        "Enabled": true,
        "MinimumLevel": "Information"
      }
    }
  }
}

Полная конфигурация

Через код:

services.AddPrimaLogger(config =>
{
    config.ApplicationName = "MyWebApp";
    
    // Консоль - только важные сообщения
    config.Console = new ConsoleLoggerOptions
    {
        MinimumLevel = LogLevel.Information,
        OutputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
    };
    
    // Файл - детальное логирование
    config.File = new FileLoggerOptions
    {
        Path = "logs/app-.log",
        MinimumLevel = LogLevel.Debug,
        OutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}",
        RollingInterval = RollingInterval.Day,
        FileSizeLimitBytes = 100 * 1024 * 1024, // 100MB
        RetainedFileCountLimit = 30
    };
    
    // Отдельный файл для ошибок
    config.ErrorFile = new FileLoggerOptions
    {
        Path = "logs/errors-.log",
        MinimumLevel = LogLevel.Error,
        RollingInterval = RollingInterval.Day,
        RetainedFileCountLimit = 90
    };
    
    // Elasticsearch - все логи
    config.Elasticsearch = new ElasticsearchSinkOptions
    {
        MinimumLevel = LogLevel.Verbose,
        Options = new ElasticsearchLoggerOptions
        {
            Nodes = { new Uri("http://localhost:9200") },
            DataStreamName = "logs-mywebapp-prod",
            ApiKey = "your-api-key",
            BootstrapMethod = BootstrapMethod.Silent,
            BufferOptions = ElasticsearchBufferOptions.HighThroughput()
        }
    };
    
    // Дополнительные свойства для всех логов
    config.CustomProperties.Add("Environment", "Production");
    config.CustomProperties.Add("Version", "1.0.0");
});

Через appsettings.json:

{
  "Logging": {
    "PrimaLogger": {
      "ApplicationName": "MyWebApp",
      "CustomProperties": {
        "Environment": "Production",
        "Version": "1.0.0"
      },
      "Console": {
        "Enabled": true,
        "MinimumLevel": "Information",
        "OutputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
      },
      "File": {
        "Path": "logs/app-.log",
        "MinimumLevel": "Debug",
        "OutputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}",
        "RollingInterval": "Day",
        "FileSizeLimitBytes": 104857600,
        "RetainedFileCountLimit": 30,
        "RollOnFileSizeLimit": true,
        "Shared": false
      },
      "ErrorFile": {
        "Path": "logs/errors-.log",
        "MinimumLevel": "Error",
        "RollingInterval": "Day",
        "RetainedFileCountLimit": 90
      },
      "Elasticsearch": {
        "MinimumLevel": "Verbose",
        "Options": {
          "Nodes": ["http://localhost:9200"],
          "DataStreamName": "logs-mywebapp-prod",
          "ApiKey": "your-api-key",
          "BootstrapMethod": "Silent",
          "BufferOptions": {
            "ConcurrentConsumers": 4,
            "InboundBufferMaxSize": 500000,
            "OutboundBufferMaxSize": 5000
          }
        }
      }
    }
  }
}

Output Template - Форматирование вывода

Основные переменные

Переменная Описание Пример
{Timestamp} Время события 2024-01-15 14:30:25.123
{Level} Уровень логирования INFO, ERROR, DEBUG
{Message} Текст сообщения User logged in successfully
{Exception} Информация об исключении Stack trace ошибки
{NewLine} Перенос строки \r\n
{ThreadId} ID потока 1, 5, 12
{SourceContext} Имя класса/логгера MyApp.Controllers.UserController
{Application} Название приложения MyWebApp
{Environment} Окружение Production, Development
{MachineName} Имя машины WEB-SERVER-01
{ProcessId} ID процесса 1234
{ProcessName} Имя процесса MyWebApp

Форматирование переменных

Timestamp - Время
{Timestamp:yyyy-MM-dd HH:mm:ss}     // 2024-01-15 14:30:25
{Timestamp:HH:mm:ss.fff}            // 14:30:25.123
{Timestamp:dd/MM/yyyy}              // 15/01/2024
{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}  // 2024-01-15 14:30:25.123 +03:00
Level - Уровень логирования
{Level}           // Information
{Level:u3}        // INF (верхний регистр, 3 символа)
{Level:w3}        // Inf (первая заглавная, 3 символа)
{Level:t3}        // inf (нижний регистр, 3 символа)
{Level:u4}        // INFO (верхний регистр, 4 символа)
Message - Сообщение
{Message}         // Обычный вывод
{Message:lj}      // Literal JSON (безопасный для JSON)
{Message:j}       // JSON escaping

Готовые шаблоны

Консоль - простой
"[{Level:u3}] {Message:lj}{NewLine}{Exception}"

Вывод:

[INF] User logged in successfully
[ERR] Database connection failed
Консоль - подробный
"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"

Вывод:

[14:30:25 INF] User logged in successfully
[14:30:26 ERR] Database connection failed
Файл - стандартный
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"

Вывод:

2024-01-15 14:30:25.123 +03:00 [INF] User logged in successfully
2024-01-15 14:30:26.456 +03:00 [ERR] Database connection failed
Файл - с контекстом
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}"

Вывод:

2024-01-15 14:30:25.123 +03:00 [INF] [1] MyApp.Controllers.UserController: User logged in successfully
2024-01-15 14:30:26.456 +03:00 [ERR] [5] MyApp.Services.DatabaseService: Database connection failed
Файл - максимальный контекст
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{Application}] [{Environment}] [{ThreadId}] [{ProcessId}] {SourceContext}: {Message:lj}{NewLine}{Exception}"

Вывод:

2024-01-15 14:30:25.123 +03:00 [INF] [MyWebApp] [Production] [1] [1234] MyApp.Controllers.UserController: User logged in successfully

Примеры конфигураций

Разработка - только консоль и файл

services.AddPrimaLogger(config =>
{
    config.Console = new ConsoleLoggerOptions
    {
        MinimumLevel = LogLevel.Debug,
        OutputTemplate = "{Timestamp:HH:mm:ss.fff} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
    };
    
    config.File = new FileLoggerOptions
    {
        Path = "logs/debug-.log",
        MinimumLevel = LogLevel.Debug,
        RollingInterval = RollingInterval.Hour,
        FileSizeLimitBytes = 50 * 1024 * 1024,
        RetainedFileCountLimit = 48
    };
});

Продакшн - все синки с разными уровнями

services.AddPrimaLogger(config =>
{
    config.Console = new ConsoleLoggerOptions
    {
        MinimumLevel = LogLevel.Warning, // Только предупреждения и ошибки
        OutputTemplate = "[{Level:u3}] {Message:lj}{NewLine}{Exception}"
    };
    
    config.File = new FileLoggerOptions
    {
        MinimumLevel = LogLevel.Information, // Общие логи
        Path = "logs/app-.log"
    };
    
    config.ErrorFile = new FileLoggerOptions
    {
        Path = "logs/errors-.log",
        MinimumLevel = LogLevel.Error,
        RollingInterval = RollingInterval.Day,
        RetainedFileCountLimit = 90
    };
    
    config.Elasticsearch = new ElasticsearchSinkOptions
    {
        MinimumLevel = LogLevel.Verbose, // Все в Elasticsearch
        Options = new ElasticsearchLoggerOptions()
            .WithApiKey("your-key")
    };
});

Уровни логирования

Уровень Назначение Когда использовать
Verbose Максимально детальная информация Глубокая отладка, трассировка
Debug Отладочная информация Разработка, диагностика
Information Общая информация Нормальное выполнение программы
Warning Предупреждения Потенциальные проблемы
Error Ошибки Ошибки, которые не ломают приложение
Fatal Критические ошибки Ошибки, которые ломают приложение

Использование в коде

using PrimaLogger;

// Через статический класс
Log.Information("User {UserId} logged in", userId);
Log.Error(exception, "Failed to process order {OrderId}", orderId);
Log.Debug("Processing started at {Timestamp}", DateTime.Now);

// Через ILogger<T> (DI)
public class UserController : ControllerBase
{
    private readonly ILogger<UserController> _logger;
    
    public UserController(ILogger<UserController> logger)
    {
        _logger = logger;
    }
    
    public IActionResult Login(string userId)
    {
        _logger.LogInformation("User {UserId} attempting login", userId);
        // ...
    }
}

Готовые Presets

// FullStack preset - консоль + файл + файл ошибок + Elasticsearch
services.AddPrimaLogger("MyApp", "http://localhost:9200", "api-key");

// Используя конфигурационные presets
services.AddPrimaLogger(config => PrimaLoggerConfig.Development("MyApp"));
services.AddPrimaLogger(config => PrimaLoggerConfig.Production("MyApp", "http://es:9200", "key"));

// Используя LoggerPresets напрямую (без DI)
var logger = LoggerPresets.Development();
var logger = LoggerPresets.WithElasticsearch("http://es:9200", "myapp");
var logger = LoggerPresets.FullStack("myapp", "http://es:9200", "api-key");

Ротация файлов

По времени

config.File = new FileLoggerOptions
{
    RollingInterval = RollingInterval.Hour,   // Каждый час
    RetainedFileCountLimit = 48               // Хранить 48 файлов (2 дня)
};

По размеру

config.File = new FileLoggerOptions
{
    RollingInterval = RollingInterval.Infinite,
    FileSizeLimitBytes = 50 * 1024 * 1024,    // 50MB
    RollOnFileSizeLimit = true,
    RetainedFileCountLimit = 10
};

Elasticsearch настройки

Производительность

config.Elasticsearch = new ElasticsearchSinkOptions
{
    Options = new ElasticsearchLoggerOptions
    {
        BufferOptions = new ElasticsearchBufferOptions
        {
            ConcurrentConsumers = 4,        // 4 потока отправки
            InboundBufferMaxSize = 500000,  // Буфер входящих
            OutboundBufferMaxSize = 5000    // Размер пакета отправки
        }
    }
};

Аутентификация

// API Key
.WithApiKey("your-api-key")

// Basic Auth
.WithBasicAuth("username", "password")

Готовые методы для Elasticsearch

ElasticsearchLoggerOptions

// Базовые настройки
ElasticsearchLoggerOptions.Default()

// Настройки буферизации
ElasticsearchBufferOptions.Default()
ElasticsearchBufferOptions.HighThroughput()  // 4 consumer, 500k/5k buffers
ElasticsearchBufferOptions.LowThroughput()   // 1 consumer, 10k/100 buffers

ElasticsearchSinkOptions

// Обертка с MinimumLevel
ElasticsearchSinkOptions.Default()           // Information уровень
ElasticsearchSinkOptions.Verbose(url)        // Verbose уровень

Пример использования:

config.Elasticsearch = ElasticsearchSinkOptions.Verbose("http://localhost:9200");

// Или с настройкой буферизации
config.Elasticsearch = new ElasticsearchSinkOptions
{
    MinimumLevel = LogLevel.Debug,
    Options = ElasticsearchLoggerOptions.Default()
        .WithApiKey("key")
        .WithBuffering(buf => buf = ElasticsearchBufferOptions.HighThroughput())
};
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 237 7/26/2025
2.0.6 370 7/25/2025
2.0.5 380 7/25/2025
2.0.4 377 7/25/2025
2.0.3 432 7/24/2025
2.0.2 113 7/17/2025
2.0.1 107 7/17/2025
2.0.0 114 7/17/2025
1.1.0 110 7/16/2025
1.0.9 111 7/16/2025
1.0.8 113 7/16/2025
1.0.7 116 7/16/2025
1.0.6 109 7/16/2025
1.0.5 111 7/16/2025
1.0.4 114 7/16/2025
1.0.3 114 7/16/2025
1.0.2 115 7/15/2025
1.0.1 114 7/15/2025
1.0.0 113 7/15/2025

v1.0.0: Первый релиз
           - Поддержка файлового логирования с ротацией
           - Поддержка Elasticsearch
           - Fluent API для конфигурации
           - Поддержка .NET Standard 2.0

           v1.0.5: Небольшой рефакторинг, разделение синков на разные MessageLevel
           - Теперь все синки имеют свой MessageLevel
           - Синки без объявления в конфиге будут автоматически отключены
           - Полное README по всем темам