Appearance
Querying Audit Logs
This guide covers all the ways to query and retrieve audit logs in GrydAudit.
Query Options
GrydAudit provides multiple ways to query audit logs:
- MediatR Queries - CQRS pattern for application layer
- Repository - Direct data access
- REST API - HTTP endpoints for external access
MediatR Queries
Get Audit Log by ID
csharp
var query = new GetAuditLogByIdQuery(auditLogId);
var result = await mediator.Send(query);
if (result is not null)
{
Console.WriteLine($"Action: {result.Action}");
Console.WriteLine($"Entity: {result.EntityType} ({result.EntityId})");
Console.WriteLine($"User: {result.UserName}");
}1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Get Entity History
Retrieve all audit logs for a specific entity:
csharp
var query = new GetAuditLogsByEntityQuery("Product", productId);
var logs = await mediator.Send(query);
foreach (var log in logs)
{
Console.WriteLine($"{log.Timestamp}: {log.Action} by {log.UserName}");
}1
2
3
4
5
6
7
2
3
4
5
6
7
Get User's Audit Logs
Retrieve all actions performed by a specific user:
csharp
var query = new GetAuditLogsByUserQuery(userId);
var logs = await mediator.Send(query);1
2
2
Search with Filters
Perform complex searches with multiple filter criteria:
csharp
var query = new SearchAuditLogsQuery(new AuditLogFilter
{
EntityType = "Product",
Action = EntityChangeType.Updated,
FromDate = DateTime.UtcNow.AddDays(-7),
ToDate = DateTime.UtcNow,
UserId = specificUserId,
TenantId = tenantId,
Skip = 0,
Take = 50
});
var result = await mediator.Send(query);
Console.WriteLine($"Found {result.TotalCount} records");
foreach (var log in result.Items)
{
// Process results
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Repository Direct Access
For scenarios where you need direct data access:
csharp
public class AuditReportService
{
private readonly IAuditLogRepository _repository;
public AuditReportService(IAuditLogRepository repository)
{
_repository = repository;
}
public async Task<IEnumerable<AuditLog>> GetRecentChangesAsync()
{
return await _repository.SearchAsync(new AuditLogFilter
{
FromDate = DateTime.UtcNow.AddHours(-24),
Take = 100
});
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Repository Methods
| Method | Description |
|---|---|
GetByIdAsync(id) | Get single audit log by ID |
GetByEntityAsync(type, id) | Get all logs for an entity |
GetByUserAsync(userId) | Get all logs for a user |
SearchAsync(filter) | Search with filter criteria |
REST API
Get by ID
http
GET /api/auditlogs/{id}1
Response:
json
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entityType": "Product",
"entityId": "a1b2c3d4-...",
"action": "Updated",
"timestamp": "2026-02-07T10:30:00Z",
"userId": "user123",
"userName": "John Doe",
"details": [
{
"propertyName": "Price",
"oldValue": "99.99",
"newValue": "149.99"
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Get Entity History
http
GET /api/auditlogs/entity/{entityType}/{entityId}1
Example:
http
GET /api/auditlogs/entity/Product/a1b2c3d4-5678-90ab-cdef-1234567890121
Get User's Logs
http
GET /api/auditlogs/user/{userId}1
Search with Filters
http
GET /api/auditlogs/search?entityType=Product&action=Updated&fromDate=2026-02-01&toDate=2026-02-07&skip=0&take=501
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
entityType | string | Filter by entity type name |
entityId | Guid | Filter by specific entity ID |
action | string | Filter by action (Created, Updated, Deleted) |
userId | string | Filter by user ID |
tenantId | Guid | Filter by tenant ID |
fromDate | DateTime | Start date (UTC) |
toDate | DateTime | End date (UTC) |
skip | int | Records to skip (pagination) |
take | int | Records to take (max 100) |
Filter Object
The AuditLogFilter class supports the following properties:
csharp
public class AuditLogFilter
{
public string? EntityType { get; set; }
public Guid? EntityId { get; set; }
public EntityChangeType? Action { get; set; }
public string? UserId { get; set; }
public Guid? TenantId { get; set; }
public DateTime? FromDate { get; set; }
public DateTime? ToDate { get; set; }
public int Skip { get; set; } = 0;
public int Take { get; set; } = 50;
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Search Results
The SearchAsync method returns an AuditLogSearchResult:
csharp
public class AuditLogSearchResult
{
public IReadOnlyList<AuditLog> Items { get; set; }
public int TotalCount { get; set; }
public int Skip { get; set; }
public int Take { get; set; }
}1
2
3
4
5
6
7
2
3
4
5
6
7
Pagination Example
csharp
var pageSize = 20;
var currentPage = 1;
var result = await mediator.Send(new SearchAuditLogsQuery(new AuditLogFilter
{
EntityType = "Order",
Skip = (currentPage - 1) * pageSize,
Take = pageSize
}));
var totalPages = (int)Math.Ceiling(result.TotalCount / (double)pageSize);
Console.WriteLine($"Page {currentPage} of {totalPages}");1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Performance Tips
- Use Date Filters: Always specify
FromDateandToDatefor large datasets - Limit Results: Use
Taketo limit the number of returned records - Index EntityType/EntityId: Ensure database indexes on frequently queried columns
- Archive Old Logs: Implement retention policies for historical data
Audit Log Details
Each AuditLog contains a collection of AuditLogDetail records showing property changes:
csharp
var log = await mediator.Send(new GetAuditLogByIdQuery(id));
foreach (var detail in log.Details)
{
Console.WriteLine($"Property: {detail.PropertyName}");
Console.WriteLine($" Old: {detail.OldValue}");
Console.WriteLine($" New: {detail.NewValue}");
}1
2
3
4
5
6
7
8
2
3
4
5
6
7
8