You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否从Microsoft.OWIN.Hosting.WebApp自托管中获取IIS类型日志?

捕获C#自托管应用的IIS类型日志的实现方法

以下是几种针对C#自托管应用(如ASP.NET Core自托管场景)的可行实现方案:

1. 自定义中间件手动生成IIS格式日志

通过中间件拦截每一次HTTP请求与响应,提取IIS日志包含的核心字段(客户端IP、请求方法、URL、状态码、响应大小、耗时等),按照IIS的W3C日志格式拼接内容并持久化。

示例代码(ASP.NET Core中间件):

public class IisStyleLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly string _logFilePath = Path.Combine(AppContext.BaseDirectory, "iis-style-logs.log");

    public IisStyleLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var startTime = DateTime.UtcNow;
        var originalResponseBody = context.Response.Body;

        // 捕获响应内容长度
        using var responseBodyStream = new MemoryStream();
        context.Response.Body = responseBodyStream;

        try
        {
            await _next(context);

            responseBodyStream.Seek(0, SeekOrigin.Begin);
            var responseSize = responseBodyStream.Length;
            await responseBodyStream.CopyToAsync(originalResponseBody);

            // 构造IIS格式日志条目
            var logEntry = $"{startTime:yyyy-MM-dd HH:mm:ss} " +
                           $"{context.Connection.RemoteIpAddress} " +
                           $"{context.Request.Method} " +
                           $"\"{context.Request.Path}{context.Request.QueryString}\" " +
                           $"{context.Response.StatusCode} " +
                           $"{responseSize} " +
                           $"{(DateTime.UtcNow - startTime).TotalMilliseconds:F0}";

            // 异步写入日志文件(生产环境建议批量处理优化性能)
            await File.AppendAllTextAsync(_logFilePath, logEntry + Environment.NewLine);
        }
        finally
        {
            context.Response.Body = originalResponseBody;
        }
    }
}

// 扩展方法注册中间件
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseIisStyleLogging(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<IisStyleLoggingMiddleware>();
    }
}

在Program.cs中添加app.UseIisStyleLogging();即可启用。

2. 利用日志框架适配IIS格式

借助Serilog这类灵活的日志库,通过自定义输出模板匹配IIS的W3C日志格式,同时利用其文件Sink实现高效持久化。

示例配置(ASP.NET Core):

var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.File(
        path: Path.Combine(AppContext.BaseDirectory, "iis-style-logs.log"),
        outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} {RemoteIpAddress} {RequestMethod} \"{RequestPath}{RequestQueryString}\" {StatusCode} {ElapsedMilliseconds}",
        rollingInterval: RollingInterval.Day)
    .CreateLogger();

builder.Host.UseSerilog();

// 注册Http上下文访问器
builder.Services.AddHttpContextAccessor();

var app = builder.Build();

// 配置请求日志,提取所需字段到日志上下文
app.UseSerilogRequestLogging(options =>
{
    options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
    {
        diagnosticContext.Set("RemoteIpAddress", httpContext.Connection.RemoteIpAddress);
        diagnosticContext.Set("RequestMethod", httpContext.Request.Method);
        diagnosticContext.Set("RequestPath", httpContext.Request.Path);
        diagnosticContext.Set("RequestQueryString", httpContext.Request.QueryString);
        diagnosticContext.Set("StatusCode", httpContext.Response.StatusCode);
    };
});

这种方式无需手动拼接日志内容,借助日志框架的能力实现格式统一和高效写入。

3. Windows环境下整合事件日志(可选)

如果应用运行在Windows系统上,可将日志写入Windows事件日志,后续通过事件查看器导出为类似IIS的格式,或配置事件日志收集规则匹配需求,适合需要和系统级日志整合的场景。

内容的提问来源于stack exchange,提问作者TheBigOnion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:45:47