Ecng.Server.Utils
1.0.125
dotnet add package Ecng.Server.Utils --version 1.0.125
NuGet\Install-Package Ecng.Server.Utils -Version 1.0.125
<PackageReference Include="Ecng.Server.Utils" Version="1.0.125" />
<PackageVersion Include="Ecng.Server.Utils" Version="1.0.125" />
<PackageReference Include="Ecng.Server.Utils" />
paket add Ecng.Server.Utils --version 1.0.125
#r "nuget: Ecng.Server.Utils, 1.0.125"
#:package Ecng.Server.Utils@1.0.125
#addin nuget:?package=Ecng.Server.Utils&version=1.0.125
#tool nuget:?package=Ecng.Server.Utils&version=1.0.125
Server.Utils
Utilities for hosting and managing background services, providing service path helpers, logging integration, and configuration management.
Overview
Server.Utils is a library designed to simplify the creation and management of background services and server applications. It provides:
- Service path and directory utilities
- Integration with Microsoft.Extensions.Logging
- Log management and configuration
- Base settings classes for server applications
Installation
This library is part of the Ecng framework and targets .NET Standard 2.0, .NET 6.0, and .NET 10.0.
Components
ServicePath
Static utility class providing service directory paths and logging configuration.
Service Directory Properties
Access common service directories:
using Ecng.Server.Utils;
// Get the directory where the service executable is located
string serviceDirectory = ServicePath.ServiceDir;
Console.WriteLine($"Service directory: {serviceDirectory}");
// Get the data directory (ServiceDir/Data)
string dataDirectory = ServicePath.DataDir;
Console.WriteLine($"Data directory: {dataDirectory}");
Create and Configure LogManager
Create a fully configured LogManager with file logging and service logging:
using Ecng.Server.Utils;
using Ecng.Logging;
using Microsoft.Extensions.Logging;
public class MyService
{
private readonly ILogger<MyService> _logger;
private readonly LogManager _logManager;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
// Create LogManager with automatic configuration
_logManager = logger.CreateLogManager(
dataDir: ServicePath.DataDir,
defaultLevel: LogLevels.Info
);
// Use the log manager
_logManager.Sources.Add(new LogSource { Name = "MyService" });
}
public void DoWork()
{
// Log through Ecng LogManager
var source = _logManager.Sources[0];
source.AddInfoLog("Service is working...");
// Also logs to Microsoft.Extensions.Logging via ServiceLogListener
}
}
Service Restart
Trigger a service restart:
using Ecng.Server.Utils;
public void RestartService()
{
// This will exit with code 1, which can be configured
// in service configuration to trigger automatic restart
ServicePath.Restart();
}
ServiceLogListener
Bridges Ecng logging to Microsoft.Extensions.Logging, allowing you to use both logging systems simultaneously.
Basic Usage
using Ecng.Logging;
using Ecng.Server.Utils;
using Microsoft.Extensions.Logging;
// In your service startup
ILogger logger = loggerFactory.CreateLogger("MyService");
var logManager = new LogManager();
// Add the service log listener
logManager.Listeners.Add(new ServiceLogListener(logger));
// Now all logs written to LogManager will also appear in Microsoft.Extensions.Logging
var source = new LogSource { Name = "MySource" };
logManager.Sources.Add(source);
source.AddInfoLog("This message appears in both logging systems");
Integration with ASP.NET Core
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Ecng.Logging;
using Ecng.Server.Utils;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Get logger from DI
var logger = app.Services.GetRequiredService<ILogger<Program>>();
// Create LogManager with ServiceLogListener integration
var logManager = logger.CreateLogManager(
ServicePath.DataDir,
LogLevels.Debug
);
// Use LogManager in your application
app.Run();
Log Level Mapping
The ServiceLogListener maps Ecng log levels to Microsoft.Extensions.Logging levels:
| Ecng LogLevel | Microsoft.Extensions.Logging |
|---|---|
| Verbose | Trace |
| Debug | Debug |
| Info | Information |
| Warning | Warning |
| Error | Error |
ServiceSettingsBase
Abstract base class for service settings with common configuration properties.
Create Custom Settings
using Ecng.Server.Utils;
using Ecng.Logging;
public class MyServiceSettings : ServiceSettingsBase
{
public MyServiceSettings()
{
// Set default values
WebApiAddress = "http://localhost:5000";
LogLevel = LogLevels.Info;
}
// Add your custom settings
public string DatabaseConnectionString { get; set; }
public int MaxConcurrentRequests { get; set; } = 100;
public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(30);
}
Use Settings in Service
using Ecng.Server.Utils;
using Microsoft.Extensions.Configuration;
public class MyService
{
private readonly MyServiceSettings _settings;
public MyService(IConfiguration configuration)
{
_settings = new MyServiceSettings
{
WebApiAddress = configuration["WebApi:Address"],
LogLevel = Enum.Parse<LogLevels>(configuration["Logging:Level"]),
DatabaseConnectionString = configuration["Database:ConnectionString"]
};
}
public void Start()
{
Console.WriteLine($"Starting web API at {_settings.WebApiAddress}");
Console.WriteLine($"Log level: {_settings.LogLevel}");
}
}
Complete Usage Examples
Windows Service with Logging
using Ecng.Logging;
using Ecng.Server.Utils;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
}
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private LogManager _logManager;
public Worker(ILogger<Worker> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Initialize LogManager with file logging
_logManager = _logger.CreateLogManager(
ServicePath.DataDir,
LogLevels.Info
);
var source = new LogSource { Name = "Worker" };
_logManager.Sources.Add(source);
while (!stoppingToken.IsCancellationRequested)
{
source.AddInfoLog("Worker running at: {Time}", DateTimeOffset.Now);
await Task.Delay(10000, stoppingToken);
}
}
public override void Dispose()
{
_logManager?.Dispose();
base.Dispose();
}
}
ASP.NET Core Service with Custom Settings
using Ecng.Logging;
using Ecng.Server.Utils;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var builder = WebApplication.CreateBuilder(args);
// Configure settings
var settings = new MyServiceSettings
{
WebApiAddress = builder.Configuration["WebApi:Address"],
LogLevel = Enum.Parse<LogLevels>(builder.Configuration["Logging:DefaultLevel"] ?? "Info")
};
builder.Services.AddSingleton(settings);
var app = builder.Build();
// Initialize logging
var logger = app.Services.GetRequiredService<ILogger<Program>>();
var logManager = logger.CreateLogManager(ServicePath.DataDir, settings.LogLevel);
app.MapGet("/", () => "Service is running");
app.MapGet("/restart", () =>
{
Task.Run(() => ServicePath.Restart());
return "Restarting...";
});
app.Run(settings.WebApiAddress);
Standalone Console Application
using Ecng.Logging;
using Ecng.Server.Utils;
using Microsoft.Extensions.Logging;
class Program
{
static void Main(string[] args)
{
// Setup Microsoft.Extensions.Logging
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});
var logger = loggerFactory.CreateLogger<Program>();
// Create LogManager with dual logging
var logManager = logger.CreateLogManager(
ServicePath.DataDir,
LogLevels.Debug
);
// Add a source
var source = new LogSource { Name = "MyApp" };
logManager.Sources.Add(source);
// Log messages (appears in both console and file)
source.AddInfoLog("Application started");
source.AddDebugLog("Debug information");
source.AddWarningLog("Warning message");
// Application logic
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
source.AddInfoLog("Application stopped");
logManager.Dispose();
}
}
Configuration Files
The LogManager created by CreateLogManager automatically saves and loads settings:
ServiceDir/
Data/
logManager.json (or .xml depending on serializer)
Logs/
2025-12-20/
logs.txt
Example logManager.json:
{
"Application": {
"LogLevel": "Info"
},
"Listeners": [
{
"Type": "FileLogListener",
"Append": true,
"FileName": "logs",
"LogDirectory": "C:\\Service\\Data\\Logs",
"SeparateByDates": "SubDirectories"
}
]
}
Requirements
- .NET Standard 2.0, .NET 6.0, or .NET 10.0
- Dependencies:
- Ecng.Logging
- Ecng.Serialization
- Microsoft.Extensions.Logging (for ServiceLogListener)
Notes
ServicePath.Restart()exits with code 1; configure your service manager to restart on this exit code- Log settings are automatically persisted to the data directory
- File logs are automatically separated by date into subdirectories
- ServiceLogListener does not support persistence (CanSave = false)
Thread Safety
ServicePath: Thread-safe (static properties and methods)ServiceLogListener: Thread-safe for logging operationsServiceSettingsBase: Not thread-safe; properties should be set during initialization
License
Part of the Ecng framework. See the main repository for licensing information.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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. |
-
.NETStandard 2.0
- Ecng.Logging (>= 1.0.126)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
-
net10.0
- Ecng.Logging (>= 1.0.126)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.1)
-
net6.0
- Ecng.Logging (>= 1.0.126)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Ecng.Server.Utils:
| Package | Downloads |
|---|---|
|
StockSharp.Studio.Runner
Runner - cross platform application to run any types of strategies |
|
|
StockSharp.Hydra.Server
Hydra server |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.125 | 24 | 1/6/2026 |
| 1.0.124 | 26 | 1/6/2026 |
| 1.0.123 | 26 | 1/6/2026 |
| 1.0.122 | 42 | 1/4/2026 |
| 1.0.121 | 45 | 1/1/2026 |
| 1.0.120 | 88 | 12/31/2025 |
| 1.0.119 | 84 | 12/30/2025 |
| 1.0.118 | 83 | 12/30/2025 |
| 1.0.117 | 82 | 12/29/2025 |
| 1.0.116 | 86 | 12/29/2025 |
| 1.0.115 | 85 | 12/26/2025 |
| 1.0.114 | 80 | 12/26/2025 |
| 1.0.113 | 86 | 12/26/2025 |
| 1.0.112 | 100 | 12/26/2025 |
| 1.0.111 | 174 | 12/25/2025 |
| 1.0.110 | 171 | 12/25/2025 |
| 1.0.109 | 170 | 12/24/2025 |
| 1.0.108 | 172 | 12/22/2025 |
| 1.0.107 | 150 | 12/21/2025 |
| 1.0.106 | 200 | 12/19/2025 |
| 1.0.105 | 232 | 12/19/2025 |
| 1.0.104 | 266 | 12/17/2025 |
| 1.0.103 | 255 | 12/15/2025 |
| 1.0.102 | 249 | 12/15/2025 |
| 1.0.101 | 242 | 12/15/2025 |
| 1.0.100 | 214 | 12/14/2025 |
| 1.0.99 | 155 | 12/14/2025 |
| 1.0.98 | 158 | 12/13/2025 |
| 1.0.97 | 164 | 12/13/2025 |
| 1.0.96 | 120 | 12/12/2025 |
| 1.0.95 | 113 | 12/12/2025 |
| 1.0.94 | 118 | 12/12/2025 |
| 1.0.93 | 110 | 12/12/2025 |
| 1.0.92 | 111 | 12/12/2025 |
| 1.0.91 | 120 | 12/12/2025 |
| 1.0.90 | 119 | 12/12/2025 |
| 1.0.89 | 662 | 12/2/2025 |
| 1.0.88 | 664 | 12/2/2025 |
| 1.0.87 | 671 | 12/2/2025 |
| 1.0.86 | 255 | 11/30/2025 |
| 1.0.85 | 118 | 11/29/2025 |
| 1.0.84 | 124 | 11/28/2025 |
| 1.0.83 | 138 | 11/28/2025 |
| 1.0.82 | 181 | 11/27/2025 |
| 1.0.81 | 184 | 11/24/2025 |
| 1.0.80 | 188 | 11/24/2025 |
| 1.0.79 | 182 | 11/23/2025 |
| 1.0.78 | 165 | 11/23/2025 |
| 1.0.77 | 207 | 11/22/2025 |
| 1.0.76 | 396 | 11/20/2025 |
| 1.0.75 | 405 | 11/18/2025 |
| 1.0.74 | 399 | 11/18/2025 |
| 1.0.73 | 282 | 11/13/2025 |
| 1.0.72 | 246 | 11/10/2025 |
| 1.0.71 | 147 | 11/1/2025 |
| 1.0.70 | 185 | 10/28/2025 |
| 1.0.69 | 185 | 10/27/2025 |
| 1.0.68 | 187 | 10/27/2025 |
| 1.0.67 | 112 | 10/25/2025 |
| 1.0.66 | 127 | 10/24/2025 |
| 1.0.65 | 189 | 10/20/2025 |
| 1.0.64 | 194 | 10/12/2025 |
| 1.0.63 | 134 | 10/11/2025 |
| 1.0.62 | 179 | 10/7/2025 |
| 1.0.61 | 193 | 10/6/2025 |
| 1.0.60 | 135 | 10/3/2025 |
| 1.0.59 | 181 | 10/1/2025 |
| 1.0.58 | 188 | 10/1/2025 |
| 1.0.57 | 186 | 9/30/2025 |
| 1.0.56 | 192 | 9/28/2025 |
| 1.0.55 | 193 | 9/25/2025 |
| 1.0.54 | 507 | 9/5/2025 |
| 1.0.53 | 194 | 9/2/2025 |
| 1.0.52 | 330 | 8/30/2025 |
| 1.0.51 | 225 | 8/30/2025 |
| 1.0.50 | 184 | 8/20/2025 |
| 1.0.49 | 177 | 8/20/2025 |
| 1.0.48 | 179 | 8/19/2025 |
| 1.0.47 | 159 | 8/15/2025 |
| 1.0.46 | 473 | 7/16/2025 |
| 1.0.45 | 231 | 7/14/2025 |
| 1.0.44 | 191 | 7/13/2025 |
| 1.0.43 | 185 | 7/13/2025 |
| 1.0.42 | 147 | 7/12/2025 |
| 1.0.41 | 233 | 7/8/2025 |
| 1.0.40 | 210 | 7/4/2025 |
| 1.0.39 | 187 | 7/2/2025 |
| 1.0.38 | 250 | 6/24/2025 |
| 1.0.37 | 388 | 6/16/2025 |
| 1.0.36 | 305 | 6/9/2025 |
| 1.0.35 | 250 | 6/8/2025 |
| 1.0.34 | 264 | 5/21/2025 |
| 1.0.33 | 191 | 5/21/2025 |
| 1.0.32 | 167 | 5/17/2025 |
| 1.0.31 | 347 | 5/12/2025 |
| 1.0.30 | 255 | 5/12/2025 |
| 1.0.29 | 245 | 5/12/2025 |
| 1.0.28 | 187 | 5/11/2025 |
| 1.0.27 | 190 | 5/11/2025 |
| 1.0.26 | 118 | 5/10/2025 |
| 1.0.25 | 132 | 5/10/2025 |
| 1.0.24 | 132 | 5/3/2025 |
| 1.0.23 | 256 | 4/17/2025 |
| 1.0.22 | 248 | 4/15/2025 |
| 1.0.21 | 161 | 4/12/2025 |
| 1.0.20 | 219 | 4/9/2025 |
| 1.0.19 | 480 | 3/22/2025 |
| 1.0.18 | 201 | 3/20/2025 |
| 1.0.17 | 191 | 3/20/2025 |
| 1.0.16 | 196 | 3/19/2025 |
| 1.0.15 | 401 | 2/26/2025 |
| 1.0.14 | 164 | 2/26/2025 |
| 1.0.13 | 407 | 2/12/2025 |
| 1.0.12 | 162 | 2/8/2025 |
| 1.0.11 | 163 | 2/8/2025 |
| 1.0.10 | 150 | 2/8/2025 |
| 1.0.9 | 154 | 2/6/2025 |
| 1.0.8 | 128 | 2/6/2025 |
| 1.0.7 | 146 | 2/6/2025 |
| 1.0.6 | 158 | 2/6/2025 |
| 1.0.5 | 156 | 2/6/2025 |
| 1.0.4 | 166 | 2/5/2025 |
| 1.0.3 | 154 | 2/5/2025 |
| 1.0.2 | 153 | 2/5/2025 |
| 1.0.1 | 149 | 2/4/2025 |
| 1.0.0 | 163 | 2/4/2025 |