# \`WriteTo\` JSON formatter

**URL:** <https://discuss.elastic.co/t/writeto-json-formatter/377362>\
**Category:** Elasticsearch\
**Tags:** ecs-elastic-common-schema\
**Created:** [April 22, 2025, 8:50am UTC](https://discuss.elastic.co/t/writeto-json-formatter/377362 "2025-04-22T08:50:55Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![khteh](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/khteh/32/147573_2.png) [@khteh](https://discuss.elastic.co/u/khteh)\
**Post date:** [April 22, 2025, 8:50am UTC](https://discuss.elastic.co/t/writeto-json-formatter/377362/1 "2025-04-22T08:50:55Z")

</div>

> <https://github.com/serilog-contrib/serilog-sinks-elasticsearch/issues/494>
>
> \*\*A few questions before you begin:\*\*
> 
> \> Is this an issue related to the \[Seri…log core project\](https://github.com/serilog/serilog) or one of the \[sinks\](https://github.com/serilog/serilog/wiki/Provided-Sinks) or 
> \[community projects\](https://github.com/serilog/serilog/wiki/Community-Projects).  
> This issue list is intended for Serilog Elasticsearch Sink issues. If this issue relates to another sink or to the code project, 
> please log on the related repository. Please use \[Gitter chat\](https://gitter.im/serilog/serilog) and \[Stack Overflow\](http://stackoverflow.com/questions/tagged/serilog) for discussions and questions.
> 
> 
> \*\*Does this issue relate to a new \*feature\* or an existing \*bug\*?\*\*
> \- \[\] Bug
> \- \[x\] New Feature
> 
> \*\*What version of Serilog.Sinks.Elasticsearch is affected? Please list the related NuGet package.\*\*
> 9.0.0-alpha-\*
> 
> \*\*What is the target framework and operating system? See \[target frameworks\](https://docs.microsoft.com/en-us/nuget/schema/target-frameworks) & \[net standard matrix\](https://docs.microsoft.com/en-us/dotnet/standard/net-standard).\*\*
> 
> \- \[x\] net 7.0
> \- \[x\] net 6.0
> \- \[x\] 4.8
> 
> As a part of integration effort between .NET and Elasticsearch, Elastic team provides \[Elastic Common Schema .NET\](/elastic/ecs-dotnet) repository which includes two sub-projects:
> \- \[Elastic Common Schema .NET\](/elastic/ecs-dotnet/tree/main/src/Elastic.CommonSchema#elastic-common-schema-net) which contains a full C# representation of \[Elastic Common Schema\](https://github.com/elastic/ecs) (ECS) and \`esc-\*\` index templates.
> \- \[Elastic Common Schema Serilog Text Formatter\](/elastic/ecs-dotnet/tree/main/src/Elastic.CommonSchema.Serilog#elastic-common-schema-serilog-text-formatter) which provides \`Serilog.Formatting.ITextFormatter\` implementation in the form of \`Elastic.CommonSchema.Serilog.EcsTextFormatter\`, for easy integration with Serilog:
> \`\`\`csharp
> var logger = new LoggerConfiguration()
> .WriteTo.Console(new EcsTextFormatter())
> .CreateLogger();
> \`\`\`
> 
> The issue is a follow-up to #254 and #227, containing more up-to-date information and first look at the integration.
> 
> Simple experiment with naïve \`Serilog.Sinks.Elasticsearch\` integration, where \`EcsTextFormatter\` simply replaces current default formater \`ElasticsearchJsonFormatter\`:
> \`\`\`csharp
> public static ITextFormatter CreateDefaultFormatter(ElasticsearchSinkOptions options)
> {
> //return new ElasticsearchJsonFormatter(
> // formatProvider: options.FormatProvider,
> // closingDelimiter: string.Empty,
> // serializer: options.Serializer != null ? new SerializerAdapter(options.Serializer) : null,
> // inlineFields: options.InlineFields,
> // formatStackTraceAsArray: options.FormatStackTraceAsArray
> //);
> 
> return new EcsTextFormatter();
> }
> \`\`\`
> 
> ...produces following output in Elasticsearch/Kibana v8.6.0:
> 
> !\[image\](https://user-images.githubusercontent.com/4405210/214290016-28b6a0b6-6b7d-42df-8908-df4d5478c764.png)
> 
> 
> Open questions would be:
> \- What would be minimal acceptable implementation (e.g. default \`EcsTextFormatter\` settings work just fine with Elasticsearch, using dynamic fields mapping, without any template registration)? Full implementation, with parity of features is something that would probably take a lot of rewrite effort and testing.
> \- What to do with existing formatters? Should they be supported side-by-side (at least for the moment)?

I use [GitHub - denis-peshkov/Serilog.Enrichers.HttpContext: Enriches Serilog events with client IP, Correlation Id, RequestBody, RequestQuery, HTTP request headers and information of the memory usage.](https://github.com/denis-peshkov/Serilog.Enrichers.HttpContext) to extract http header values and have the following configuration in `appsettings.json`:

```auto
        "WriteTo": [
            {
                "Name": "Console",
                    "Args": {
                        "outputTemplate": "[{Timestamp}] {Level} {EventId} IP:{ClientIp} CorrelationId:{CorrelationId} Agent:{UserAgent} ContentType:{ContentType} ContentLength:{ContentLength} RequestBody:{RequestBody} RequestQuery:{RequestQuery} MemoryUsage:{MemoryUsageExact}/{MemoryUsage} {Message:j} {Properties} {NewLine}{Exception}{NewLine}",
                        "customFormatter": "Elastic.CommonSchema.Serilog.EcsTextFormatter, Elastic.CommonSchema.Serilog"
                    }
            },

```

However, the log I get doesn't seem to be json formatted:

```auto
[04/21/2025 12:38:02 +08:00] Information { Id: 2, Name: "ResponseLog" } IP:::1 CorrelationId:null Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 ContentType:null ContentLength:null RequestBody: RequestQuery: MemoryUsage:/338575360 Response:
StatusCode: 200
Content-Type: image/x-icon
Accept-Ranges: bytes
ETag: [Redacted]
Last-Modified: Thu, 16 Jun 2022 07:02:55 GMT
Content-Length: 32038 { StatusCode: 200, Content-Type: "image/x-icon", Accept-Ranges: "bytes", ETag: "[Redacted]", Last-Modified: "Thu, 16 Jun 2022 07:02:55 GMT", Content-Length: "32038", SourceContext: "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware", RequestId: "0HNC0HP5TD59L:00000023", RequestPath: "/favicon.ico", ConnectionId: "0HNC0HP5TD59L", ThreadId: 25, X_Original_For: null, X_Forwarded_Proto: null, X_Original_Proto: null, X_Forwarded_Host: null, X_Original_Host: null } 

```

```auto
[04/21/2025 12:38:02 +08:00] Information { Id: 2 } IP:::1 CorrelationId:null Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 ContentType:image/x-icon ContentLength:32038 RequestBody: RequestQuery: MemoryUsage:/339099648 Request finished "HTTP/2" "GET" "https"://"[::1]:4433""""/favicon.ico""" - 200 32038 "image/x-icon" 10.8386ms { SourceContext: "Microsoft.AspNetCore.Hosting.Diagnostics", RequestId: "0HNC0HP5TD59L:00000023", RequestPath: "/favicon.ico", ConnectionId: "0HNC0HP5TD59L", ThreadId: 13, X_Original_For: null, X_Forwarded_Proto: null, X_Original_Proto: null, X_Forwarded_Host: null, X_Original_Host: null } 

```

---

<div class="post-metadata">

**Author:** ![Alex\_Salgado-Elastic](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/alex_salgado-elastic/32/103081_2.png) [@Alex\_Salgado-Elastic](https://discuss.elastic.co/u/Alex_Salgado-Elastic)\
**Post date:** [April 23, 2025, 12:03pm UTC](https://discuss.elastic.co/t/writeto-json-formatter/377362/2 "2025-04-23T12:03:04Z")

</div>

Hi @khteh

The issue is that you're using both `outputTemplate` and `customFormatter` together, which may be conflicting. For JSON output, try removing the `outputTemplate` and use only the `formatter` like this:

```auto
"WriteTo": [
    {
        "Name": "Console",
        "Args": {
            "formatter": "Elastic.CommonSchema.Serilog.EcsTextFormatter, Elastic.CommonSchema.Serilog"
        }
    }
]

```
