AppHost 请求的通用日志记录,包括。 ServiceStack 中的主体

Generic logging of AppHost requests incl. bodies in ServiceStack

我想记录我的 ServiceStack AppHost 尝试处理的每个 HTTP 请求。我想出了一个不错的解决方案,但我不知道这是否会在某个地方爆炸,因为我将 MemoryStream 注入 HttpListenerRequest 因为 InputStream 不会让我找回来。

我的日志

    public static void R(HttpListenerRequest request)
    {
        var guid = Guid.NewGuid().ToString().Replace("-", "");
        L(LogType.Request, "{1} Url: {0} LocalEndPoint: {2} RemoteEndPoint: {3}", request.Url, request.HttpMethod, request.LocalEndPoint.ToString(), request.RemoteEndPoint.ToString());
        foreach (var header in request.Headers.AllKeys)
        {
            Trace.WriteLine(string.Format("{0} H  {1}: {2}", (char)LogType.Request, header, request.Headers[header]));
        }
        string content = null;
        if (request.InputStream != null)
        {
            MemoryStream memStream = new MemoryStream();
            request.InputStream.CopyTo(memStream);
            request.InputStream.Close();
            request.InputStream.Dispose();
            memStream.Position = 0;
            var reader = new StreamReader(memStream);
            {
                content = reader.ReadToEnd();
                memStream.Position = 0;
                request.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                    .Where(field => field.Name == "m_RequestStream")
                    .First()
                    .SetValue(request, memStream);
            }
        }

        if (!string.IsNullOrEmpty(content))
        {
            foreach (var line in content.Split('\n'))
            {
                Trace.WriteLine(string.Format("{0} B  {1}", (char)LogType.Request, line));
            }                
        }
    }

AppHost 内部

    protected override Task ProcessRequestAsync(HttpListenerContext context)
    {
        var request = context?.Request;
        if (request != null)
        {
            Log.R(request);
        }

        return base.ProcessRequestAsync(context);
    }

如前所述,这目前正在运行,但我不敢发布它。所以也许你有一个更好的方法来记录所有带有正文的请求。

您可以使用此方法,但我建议使用 built-in Request Logger。您可以使用 EnableRequestBodyTracking=true 记录请求主体,这将启用请求主体的缓冲,配置 LimitToServiceRequests=false 也将记录非服务请求,例如:

Plugins.Add(new RequestLogsFeature {
    EnableRequestBodyTracking = true,
    LimitToServiceRequests = false,
});