CSharpEssentials.LoggerHelper.Sink.Elasticsearch
5.2.9
dotnet add package CSharpEssentials.LoggerHelper.Sink.Elasticsearch --version 5.2.9
NuGet\Install-Package CSharpEssentials.LoggerHelper.Sink.Elasticsearch -Version 5.2.9
paket add CSharpEssentials.LoggerHelper.Sink.Elasticsearch --version 5.2.9
#r "nuget: CSharpEssentials.LoggerHelper.Sink.Elasticsearch, 5.2.9"
#:package CSharpEssentials.LoggerHelper.Sink.Elasticsearch@5.2.9
#addin nuget:?package=CSharpEssentials.LoggerHelper.Sink.Elasticsearch&version=5.2.9
#tool nuget:?package=CSharpEssentials.LoggerHelper.Sink.Elasticsearch&version=5.2.9
CSharpEssentials.LoggerHelper.Sink.Elasticsearch
Elasticsearch / OpenSearch indexing with automatic index template registration for CSharpEssentials.LoggerHelper.
Targets: net8.0 · net9.0 · net10.0 — Part of the CSharpEssentials.LoggerHelper ecosystem. Install only the sinks you need.
Install
dotnet add package CSharpEssentials.LoggerHelper
dotnet add package CSharpEssentials.LoggerHelper.Sink.Elasticsearch
Quick Setup — JSON
Add to appsettings.json:
{
"LoggerHelper": {
"ApplicationName": "MyApp",
"Routes": [
{ "Sink": "Elasticsearch", "Levels": ["Information", "Warning", "Error", "Fatal"] }
],
"Sinks": {
"Elasticsearch": {
"NodeUris": "http://localhost:9200",
"IndexFormat": "myapp-logs-{0:yyyy.MM.dd}",
"AutoRegisterTemplate": true
}
}
}
}
// Program.cs
builder.Services.AddLoggerHelper(builder.Configuration);
var app = builder.Build();
app.UseLoggerHelper(); // ← required: activates sinks and registers middleware
Index template registration is automatic by default. The sink calls Elasticsearch on startup to register the index template — no manual Kibana/DevTools setup needed. This is a synchronous HTTP call (about 2 s when the node is down); set
"AutoRegisterTemplate": falseto skip it (see Configuration Options).
Quick Setup — Fluent API
builder.Services.AddLoggerHelper(b => b
.WithApplicationName("MyApp")
.AddRoute("Elasticsearch", LogEventLevel.Information, LogEventLevel.Warning, LogEventLevel.Error, LogEventLevel.Fatal)
.ConfigureElasticsearch(e => {
e.NodeUris = "http://localhost:9200";
e.IndexFormat = "myapp-logs-{0:yyyy.MM.dd}";
})
);
var app = builder.Build();
app.UseLoggerHelper(); // ← required
What You'll See
Each log event is indexed as a JSON document:
{
"@timestamp": "2026-06-01T14:23:01.123Z",
"level": "Information",
"message": "Order 42 placed by usr_99",
"messageTemplate": "Order {OrderId} placed by {UserId}",
"fields": {
"OrderId": 42,
"UserId": "usr_99",
"ApplicationName": "MyApp"
}
}
Documents land in the index matching your IndexFormat (e.g. myapp-logs-2026.06.01). Query them in Kibana, OpenSearch Dashboards, or with the Elasticsearch REST API.
Index Format
The IndexFormat string uses standard .NET date format tokens applied to the current UTC date:
| Example | Resulting index name |
|---|---|
"myapp-logs-{0:yyyy.MM.dd}" |
myapp-logs-2026.06.01 (daily) |
"myapp-logs-{0:yyyy.MM}" |
myapp-logs-2026.06 (monthly) |
"myapp-logs" |
myapp-logs (no date — single index, never rolls) |
OpenSearch Compatibility
This sink is fully compatible with OpenSearch — use the same configuration, pointing NodeUris at your OpenSearch node:
"NodeUris": "http://localhost:9200"
OpenSearch exposes the same REST API as Elasticsearch 7.x on port 9200 by default.
Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
NodeUris |
string |
"" |
Required. Elasticsearch node URL. For HTTPS or authentication include them in the URI: "https://user:pass@es-host:9243". |
IndexFormat |
string? |
null |
Index name format with optional date placeholder {0:...}. When null Serilog uses its own default. |
| AutoRegisterTemplate | bool | true | Registers the index template with a synchronous HTTP call at startup (idempotent). Set false to skip it, e.g. when the template is managed elsewhere or the node may be down at startup. Legacy JSON key autoRegisterTemplate is also accepted. |
Startup validation. An empty
NodeUris(or a missingElasticsearchsection) makes the sink fail to configure with anInvalidOperationException; LoggerHelper records it as not configured (shown as FAILED in the Dashboard/MCP) and the other sinks keep working.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| No output at all | app.UseLoggerHelper() missing |
Add it after builder.Build() |
401 Unauthorized |
Elasticsearch 8.x security is enabled by default | Include credentials in NodeUris: "https://elastic:password@localhost:9200" |
connection refused on port 9200 |
Elasticsearch is not running or wrong port | Start Elasticsearch and verify the node URL |
| Index not visible in Kibana | IndexFormat date mismatch or wrong data view pattern |
Check the index name in Elasticsearch: GET /_cat/indices?v |
| Template registration error at startup | Insufficient Elasticsearch permissions | Grant manage_index_templates privilege to the connecting user, or set AutoRegisterTemplate: false |
| Startup takes ~2 s longer when Elasticsearch is down | Template registration is a synchronous HTTP call | Set AutoRegisterTemplate: false |
| Sink shows FAILED in Dashboard/MCP, no logs sent | NodeUris empty or Elasticsearch section missing |
Set Sinks.Elasticsearch.NodeUris |
No connection could be made on WSL |
localhost resolves to IPv6, Docker only listens on IPv4 |
Use http://127.0.0.1:9200 instead of http://localhost:9200 in NodeUris |
| Index created but no documents | Elasticsearch 8.x version detection fails with the Serilog sink | This sink sets DetectElasticsearchVersion = false and AutoRegisterTemplateVersion = ESv7 internally — no action needed on your side |
Quick Local Setup with Docker
# Elasticsearch
docker run -d --name elasticsearch \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:8.13.0
# Kibana (optional — for log visualization)
docker run -d --name kibana \
--link elasticsearch:elasticsearch \
-p 5601:5601 \
docker.elastic.co/kibana/kibana:8.13.0
Then set NodeUris to "http://localhost:9200" and open Kibana at http://localhost:5601.
WSL users: if the connection times out, use
http://127.0.0.1:9200instead ofhttp://localhost:9200. WSL can routelocalhostto an IPv6 address that Docker does not expose, causing silent failures.
Viewing Logs in Kibana — Step by Step
Once your app is running and sending logs, follow these steps to visualize them.
Step 1 — Verify the index exists
- Open Kibana at
http://localhost:5601 - Open the left menu (☰) → Stack Management (gear icon at the bottom)
- Under Data → click Index Management
- Look for your index (e.g.
myapp-logs-2026.07.03) — the Docs count column must be greater than zero
If the index is missing, the sink is not writing. Check NodeUris and confirm app.UseLoggerHelper() is called.
Step 2 — Create a Data View
A Data View is how Kibana maps an index pattern to its query engine.
- Still in Stack Management → under Kibana → click Data Views
- Click Create data view
- In the Index pattern field enter:
myapp-logs-*(the*wildcard covers all daily indices) - Kibana confirms the matched indices in real time
- In the Timestamp field dropdown select
@timestamp - Click Save data view
Step 3 — Browse logs in Discover
- Open the left menu (☰) → Analytics → Discover
- Select your data view from the dropdown in the top-left (e.g.
myapp-logs-*) - Set the time filter in the top-right to Last 15 minutes (or the period when your app ran)
- Log events appear in the table — click any row to expand the full JSON document
Each document exposes all structured properties set via BeginScope or call-site parameters
(e.g. fields.ApplicationName, fields.RenderedMessage, fields.MachineName) and is fully
searchable with KQL: fields.ApplicationName : "MyApp" and level : "Error".
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net10.0
- CSharpEssentials.LoggerHelper (>= 5.2.9)
- Serilog.Sinks.Elasticsearch (>= 10.0.0)
-
net8.0
- CSharpEssentials.LoggerHelper (>= 5.2.9)
- Serilog.Sinks.Elasticsearch (>= 10.0.0)
-
net9.0
- CSharpEssentials.LoggerHelper (>= 5.2.9)
- Serilog.Sinks.Elasticsearch (>= 10.0.0)
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 |
|---|---|---|
| 5.2.9 | 0 | 10/6/2026 |
| 5.2.8 | 0 | 10/6/2026 |
| 5.2.7 | 28 | 10/6/2026 |
| 5.2.6 | 117 | 8/31/2026 |
| 5.2.4.1 | 101 | 8/27/2026 |
| 5.2.4 | 106 | 8/25/2026 |
| 5.2.3 | 100 | 8/25/2026 |
| 5.2.2.9 | 129 | 7/11/2026 |
| 5.2.2.8 | 119 | 7/11/2026 |
| 5.2.2.7 | 121 | 7/10/2026 |
| 5.2.2.6 | 116 | 7/6/2026 |
| 5.2.2.5 | 122 | 7/5/2026 |
| 5.2.2.4 | 122 | 7/5/2026 |
| 5.2.2.3 | 123 | 7/5/2026 |
| 5.2.2.2 | 134 | 7/5/2026 |
| 5.2.2.1 | 117 | 7/4/2026 |
| 5.2.2 | 122 | 7/3/2026 |
| 5.2.0 | 143 | 6/29/2026 |
| 5.1.1 | 132 | 6/19/2026 |
| 5.1.0 | 125 | 6/16/2026 |