我的请求样本
GET http://localhost:5000/api/values HTTP/1.1
cache-control: no-cache
User-Agent: PostmanRuntime/6.4.1
Accept: */*
Host: localhost:5000
accept-encoding: gzip, deflate
Connection: keep-alive
和回复
HTTP/1.1 200 OK
Date: Wed, 28 Mar 2018 07:18:08 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 19
["value1","value2"]
我希望得到所有http消息的日志
我应该如何获取请求消息和响应消息
因为我可以找到任何错误的日志(如错误请求消息(自定义TCP))
答案 0 :(得分:0)
一个选项是创建自定义中间件,然后您可以检查请求/响应以构建所需的日志。
中间件允许您在途中获取请求并在出路时获取响应。
在上下文(HttpContext)上,你应该能够得到你期望的数据 - https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.httpcontext?view=aspnetcore-2.0
答案 1 :(得分:0)
我编写了一个中间件,以nginx样式记录(几乎)访问日志。
您可以执行大致相同的操作,并在LogData
类中添加并填充自己的字段,然后更改DefaultFormatter
函数。
public class RequestLogMiddleware
{
public class LogData {
public IPAddress RemoteAddr {get;set;}
public string User {get; set;}
public int ResponseStatus {get; set;}
public string RequestMethod {get;set;}
public string RequestTimestamp {get;set;}
public string RequestPath {get;set;}
public string RequestProtocol {get;set;}
public string UserAgent {get;set;}
public long DurationMs {get;set;}
}
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public RequestLogMiddleware(RequestDelegate next, ILoggerFactory factory)
{
_next = next;
_logger = factory.CreateLogger("RequestLog");
}
private Func<LogData, string> _logLineFormatter;
private Func<LogData,string> logLineFormatter{
get {
if (this._logLineFormatter != null) {
return this._logLineFormatter;
}
return this.DefaultFormatter();
}
set {
this._logLineFormatter = value;
}
}
/// <summary>
/// Override this to set the default formatter if none was supplied
/// </summary>
/// <returns></returns>
protected Func<LogData, string> DefaultFormatter() {
return (logData => $"{logData.RemoteAddr} - {logData.User} {logData.RequestTimestamp} \"{logData.RequestMethod} {logData.RequestPath} {logData.RequestProtocol}\" {logData.ResponseStatus} \"{logData.UserAgent}\" {logData.DurationMs}ms");
}
/// <summary>
/// Used to set a custom formatter for this instance
/// </summary>
/// <param name="formatter"></param>
public void SetLogLineFormat(Func<LogData, string> formatter) {
this._logLineFormatter = formatter;
}
public async Task Invoke(HttpContext context)
{
var now = DateTime.Now;
var watch = Stopwatch.StartNew();
await _next.Invoke(context);
watch.Stop();
var nowString = now.ToString("yyyy-MM-dd'T'HH:mm:ss.fffzzz", DateTimeFormatInfo.InvariantInfo);
var user = context.User.Identity.Name ?? "-";
var request = context.Request.Path + (string.IsNullOrEmpty(context.Request.QueryString.ToString()) ? "" : context.Request.QueryString.ToString());
var responseStatus = context.Response.StatusCode;
var userAgent = context.Request.Headers.ContainsKey("User-Agent") ? context.Request.Headers["User-Agent"].ToString() : "-";
var protocol = context.Request.Protocol;
var duration = watch.ElapsedMilliseconds;
var remoteAddr = context.Connection.RemoteIpAddress;
var method = context.Request.Method;
var logData = new LogData {
RemoteAddr = remoteAddr,
RequestMethod = method,
RequestPath = request,
RequestProtocol = protocol,
RequestTimestamp = nowString,
ResponseStatus = responseStatus,
User = user,
UserAgent = userAgent,
DurationMs = duration,
};
_logger.LogInformation(this.logLineFormatter(logData));
}
}
只需通过Configure
中的Startup.cs
方法将其连接起来即可:
app.UseMiddleware(typeof(RequestLogMiddleware));
确保它是您添加的第一个中间件。
示例输出:
info: RequestLog[0]
::1 - - 2018-08-10T14:23:04.183+02:00 "GET /api/ping HTTP/1.1" 200 "-" 266ms
info: RequestLog[0]
::1 - - 2018-08-10T14:23:04.569+02:00 "POST /api/search HTTP/1.1" 401 "-" 31ms
info: RequestLog[0]
::1 - - 2018-08-10T14:23:04.375+02:00 "POST /api/search HTTP/1.1" 200 "-" 3453ms
info: RequestLog[0]
::1 - - 2018-08-10T14:23:04.375+02:00 "POST /api/search HTTP/1.1" 200 "-" 4341ms
info: RequestLog[0]
::1 - - 2018-08-10T14:23:08.932+02:00 "POST /api/search HTTP/1.1" 400 "-" 16ms
可以在配置中打开/关闭记录器:
"Logging": {
"LogLevel": {
"Default": "Warning",
"RequestLog": "Information"
}
},