Services
This page separates what DevKit already does for you from the hooks you use when you need more control.
Automatic request and pipeline logging
- HTTP requests — DevKit registers
HttpRequestLoggingMiddlewareon web hosts. It logs method, URL, headers, query string, and—unless the endpoint opts out—body and form. After the pipeline runs, it logs status code, duration, and response headers. You do not add this middleware yourself in normal template hosts. - Commands, queries, and domain events — The
MediatRDispatcherimplementation ofIRequestDispatcherlogs each message when it is received and when it completes, including timing, so you can correlate HTTP work with application-layer work in the same trace.
Together, that gives you a single narrative from “request hit the server” through “handlers ran” to “response left the server,” with ASP.NET Core log scopes (for example TraceId) tying nested ILogger calls to the same unit of work.
Console and Mongo (high level)
- Console — During local development, OpenTelemetry is wired so logs are easy to read in the console, which is usually enough to debug behavior without touching Mongo or the Admin UI.
- Mongo + Admin Panel — When the Monitoring module is enabled, logs can also be persisted and inspected in the product UI. That path is documented under Monitoring; you mainly tune
Monitoring:Logginginappsettings(see Configuration).
API response body logging
API controllers that inherit DevKit’s BaseApiController get HttpResponseLoggingAttribute, which logs JSON response bodies after actions execute unless you suppress it per action or controller.
// Copyright (c) CodeBlock.Dev. All rights reserved.
// For more information visit https://codeblock.dev
using System.Text;
using CodeBlock.DevKit.Web.Filters;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace CodeBlock.DevKit.Web.Api.Filters;
/// <summary>
/// Attribute that logs HTTP response bodies for debugging and monitoring purposes.
/// Can be applied to controllers to automatically log all response content.
/// Respects the DoNotLogResponseBody attribute to skip logging when needed.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class HttpResponseLoggingAttribute : Attribute, IAsyncResultFilter
{
/// <summary>
/// Intercepts the response execution to capture and log the response body.
/// Temporarily replaces the response stream to capture content without affecting the client.
/// </summary>
/// <param name="context">The result execution context</param>
/// <param name="next">The next filter in the pipeline</param>
/// <returns>A task representing the asynchronous operation</returns>
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
var loggerFactory = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger<HttpResponseLoggingAttribute>();
// Check if the DoNotLogResponseBody attribute is present on the controller or action
var endpoint = context.HttpContext.GetEndpoint();
var hasDoNotLogAttr = endpoint?.Metadata.GetMetadata<DoNotLogResponseBodyAttribute>() != null;
// Swap out the response body stream with a temporary memory stream
var originalBodyStream = context.HttpContext.Response.Body;
using var temporaryStream = new MemoryStream();
context.HttpContext.Response.Body = temporaryStream;
// Execute the action and response
var resultContext = await next();
var responseBody = await GetResponseBody(context.HttpContext.Response);
// Skip logging if the attribute is present
if (!hasDoNotLogAttr)
{
logger.LogInformation("Response Body: {ResponseBody}", responseBody);
}
else
{
logger.LogInformation("Response Body: response body logging is disabled for this endpoint");
}
// Reset the stream position again to copy it back to the original stream
await temporaryStream.CopyToAsync(originalBodyStream);
context.HttpContext.Response.Body = originalBodyStream;
}
/// <summary>
/// Reads and formats the response body for logging purposes.
/// Handles stream positioning and JSON formatting for better readability.
/// </summary>
/// <param name="response">The HTTP response to read the body from</param>
/// <returns>A formatted string representation of the response body</returns>
private async Task<string> GetResponseBody(HttpResponse response)
{
if (!response.Body.CanRead)
return "Response body is not readable.";
response.Body.Seek(0, SeekOrigin.Begin);
using var reader = new StreamReader(response.Body, Encoding.UTF8, leaveOpen: true);
var body = await reader.ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
if (string.IsNullOrWhiteSpace(body))
return "No Body Data!";
var jsonBody = JsonConvert.DeserializeObject(body);
return JsonConvert.SerializeObject(jsonBody, Formatting.Indented);
}
}
Redacting HTTP bodies
Endpoints can opt out of logging raw request or response bodies when they handle secrets.
// Copyright (c) CodeBlock.DevKit. All rights reserved.
// For more information visit https://codeblock.dev
namespace CodeBlock.DevKit.Web.Filters;
/// <summary>
/// Marker attribute that indicates request body content should not be logged.
/// Apply this attribute to controllers or actions to prevent logging of sensitive request data
/// such as passwords, credit card numbers, or other confidential information.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class DoNotLogRequestBodyAttribute : Attribute
{
// This is a marker attribute to indicate sensitive body data should not be logged
}
// Copyright (c) CodeBlock.DevKit. All rights reserved.
// For more information visit https://codeblock.dev
namespace CodeBlock.DevKit.Web.Filters;
/// <summary>
/// Marker attribute that indicates response body content should not be logged.
/// Apply this attribute to controllers or actions to prevent logging of sensitive response data.
/// Currently not implemented in the logging middleware but available for future use.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class DoNotLogResponseBodyAttribute : Attribute { }
HttpRequestLoggingMiddleware is internal to DevKit; your host already registers it. You influence request lines through [DoNotLogRequestBody] (and related endpoint metadata), not by replacing the middleware type.
Your own logging with ILogger
Inject ILogger or ILogger<TCategory> anywhere the host registers services. Command and query handlers that inherit BaseCommandHandler / BaseQueryHandler already expose _logger for convenience—see Tutorials.
Redacting MediatR payloads and query results
Use [DoNotLog] on types or properties and [DoNotLogQueryResult] on queries when serialized payloads should not appear in dispatcher logs. Full patterns and namespaces live in Tutorials.