---
title: "How to Save Audit Logs to ElasticSearch"
description: "ASP.NET Zero is the base solution for building robust and scalable web applications. Unlock your full potential today!"
url: "https://aspnetzero.com/blog/how-to-save-audit-logs-to-elasticsearch"
image: "https://aspnetzero.com/Images/Blog/how-to-save-audit-logs-to-elasticsearch.png"
---

[Blog](https://aspnetzero.com/blog)

# How to Save Audit Logs to ElasticSearch

13 October 2021 2 min read [Elastic Search](https://aspnetzero.com/blog/topics/elastic-search)

![How to Save Audit Logs to ElasticSearch](https://aspnetzero.com/Images/Blog/how-to-save-audit-logs-to-elasticsearch.png)

Share [X](https://twitter.com/intent/tweet?url=https%3A%2F%2Faspnetzero.com%2Fblog%2Fhow-to-save-audit-logs-to-elasticsearch&text=How+to+Save+Audit+Logs+to+ElasticSearch) [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Faspnetzero.com%2Fblog%2Fhow-to-save-audit-logs-to-elasticsearch) [Reddit](https://reddit.com/submit?url=https%3A%2F%2Faspnetzero.com%2Fblog%2Fhow-to-save-audit-logs-to-elasticsearch&title=How+to+Save+Audit+Logs+to+ElasticSearch) [Hacker News](https://news.ycombinator.com/submitlink?u=https%3A%2F%2Faspnetzero.com%2Fblog%2Fhow-to-save-audit-logs-to-elasticsearch&t=How+to+Save+Audit+Logs+to+ElasticSearch)

# Save Audit Logs to ElasticSearch in ASP.NET Zero

ASP.NET Zero provides **AuditLogging** functionality out of the box and all audit logs are saved to **database** by **default**.

In this article we will log all audit log data to [Elastic Search](https://www.elastic.co/). We assume that, you already have a working [Elastic Search](https://www.elastic.co/) which you can use for this article. If not, please install it to your PC first.

[ASP.NET Boilerplate](https://aspnetboilerplate.com/) uses [IAuditingStore](https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/Auditing/IAuditingStore.cs) to store any audit log data. See: [AuditingHelper.cs](https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp/Auditing/AuditingHelper.cs#L130-L146). To save audit logs to elasticsearch, we should create a service that implements `IAuditingStore`, then replace it with current implementation.

We will use [NEST](https://github.com/elastic/elasticsearch-net#nest) the **offical** elasticsearch .net library. Install **NEST** package to your project using the command below or NuGet Package Manager.

```shell
PM> Install-Package NEST
```

Then create new class named `ElasticSearchAuditingStore`

```csharp
using System;
using System.Threading.Tasks;
using Abp.Auditing;
using Abp.Domain.Repositories;
using Nest;

public class ElasticSearchAuditingStore : AuditingStore
{
    private const string ElasticSearchIndexName = "AUDIT_LOG_INDEX_NAME";

    public ElasticSearchAuditingStore(IRepository<AuditLog, long> auditLogRepository) : base(auditLogRepository)
    {
    }

    public override void Save(AuditInfo auditInfo)
    {
        base.Save(auditInfo);
        var client = GetClient();
        client.Index(auditInfo, x => x.Index(ElasticSearchIndexName));
    }

    public override async Task SaveAsync(AuditInfo auditInfo)
    {
        await base.SaveAsync(auditInfo);
        var client = GetClient();
        await client.IndexAsync(auditInfo, x => x.Index(ElasticSearchIndexName));
    }

    public static IElasticClient GetClient()
    {
        var node = new Uri("[YOUR_ELASTIC_SEARCH_URL]");
        var settings = new ConnectionSettings(node)
            .DefaultIndex(ElasticSearchIndexName)
            .BasicAuthentication("USERNAME", "PASSWORD");
        return new ElasticClient(settings);
    }

    public static void CreateIndexIfNeededAsync()
    {
        var client = GetClient();

        var existsResponse = client.Indices.Exists(ElasticSearchIndexName);

        if (!existsResponse.Exists)
        {
            client.Indices.Create(ElasticSearchIndexName, c => c
                .Map<AuditInfo>(m =>
                {
                    return m
                        .Properties(p => p
                            .Keyword(x => x.Name(d => d.TenantId))
                            .Keyword(x => x.Name(d => d.UserId))
                            .Keyword(x => x.Name(d => d.ImpersonatorUserId))
                            .Keyword(x => x.Name(d => d.ImpersonatorTenantId))
                            .Keyword(x => x.Name(d => d.ServiceName))
                            .Keyword(x => x.Name(d => d.MethodName))
                            .Keyword(x => x.Name(d => d.Parameters))
                            .Keyword(x => x.Name(d => d.ReturnValue))
                            .Keyword(x => x.Name(d => d.ExecutionTime))
                            .Keyword(x => x.Name(d => d.ExecutionDuration))
                            .Keyword(x => x.Name(d => d.ClientIpAddress))
                            .Keyword(x => x.Name(d => d.ClientName))
                            .Keyword(x => x.Name(d => d.BrowserInfo))
                            .Text(x => x.Name(d => d.CustomData)));
                }));
        }
    }
}
```

Now, we need to replace the default `AuditingStore` implementation with our new `ElasticSearchAuditingStore`. To do that, add following code to your module's `PreInitialize` method.

```csharp
public override void PreInitialize()
{
    ElasticSearchAuditingStore.CreateIndexIfNeededAsync();
    
    Configuration.ReplaceService<IAuditingStore, ElasticSearchAuditingStore>(DependencyLifeStyle.Transient);
}
```

After all, audit logs will be saved to elastic search. Now, you can make better search operations on your audit logs using ElasticSearch.

## Ready to build?

Get full source code, premium support, and enterprise-ready features with ASP.NET Zero.

[See pricing plans](https://aspnetzero.com/pricing)

## Have questions before purchasing?

Schedule a free consultation with our team to find the right plan for your project.

[Schedule a meeting](https://aspnetzero.com/schedule-meeting)

## You might also like

### [Business Benefits of Using ASP.NET Zero for Enterprise Software Development](https://aspnetzero.com/blog/business-benefits-of-aspnetzero)

11 September 2026

### [Common Mistakes and Errors When Hosting ASP.NET Core Apps](https://aspnetzero.com/blog/common-mistakes-and-errors-hosting-aspnet-core-apps)

26 August 2026

### [Using AutoMapper After Migrating to Mapperly](https://aspnetzero.com/blog/using-automapper-after-migrating-to-mapperly)

04 August 2026

## Recent posts

### [Business Benefits of Using ASP.NET Zero for Enterprise Software Development](https://aspnetzero.com/blog/business-benefits-of-aspnetzero)

11 September 2026

### [Common Mistakes and Errors When Hosting ASP.NET Core Apps](https://aspnetzero.com/blog/common-mistakes-and-errors-hosting-aspnet-core-apps)

26 August 2026

### [Using AutoMapper After Migrating to Mapperly](https://aspnetzero.com/blog/using-automapper-after-migrating-to-mapperly)

04 August 2026

## Start building with ASP.NET Zero

Full source code, premium support, Angular, React & MVC UI options.

[View pricing](https://aspnetzero.com/pricing)

## Topics
