使用中间件记录网站访问日志记录

对于网站访问日志的记录,一般情况下都是使用现有的日志服务,比如谷歌分析引入轻量 js 文件即可。本文主要介绍对于现有的 Asp.Net Core 网站使用中间件快速记录访问日志。使用中间件的好处:在服务端进行处理,无视客户端类型(特殊信息无法获取);统一处理,不需要对每个地址重复处理等。

直奔主题,最简单的日志信息记录主要包括了访问IP,访问时间,访问地址以及来源地址,建立一个简单的模型类如下:

public class AccessLog {
    public int Id { get; set; }
    public string Ip { get; set; }
    public string Url { get; set; }
    public string Referer { get; set; }
}

数据库持久化框架主要使用 Entity Framework Core,建立简单的 DbContext ,注册服务并执行迁移得到数据库。下一步编写日志记录中间件如下:

public class AccessLogMiddleWare
{
    private readonly RequestDelegate _next;

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

    public async Task InvokeAsync(HttpContext context, ILogger<AccessLogMiddleWare> logger, AppDbContext db)
    {
        // 切割请求地址
        var type = context.Request.Path.ToString().Split('.').Last();
        if (type == "html")
        {
            logger.LogInformation(context.Request.Path + "\t" + context.Connection.RemoteIpAddress.MapToIPv4().ToString() + "\t" + context.Request.Headers["X-Real-IP"] + "\t" + context.Request.Headers["X-Forwarded-For"] + "\t" + context.Request.Headers["Referer"]);
            //if (context.Connection.RemoteIpAddress.MapToIPv4().ToString() != "0.0.0.1") { }
            var log = new AccessLog
            {
                AccessTime = DateTime.Now,
                Ip = string.IsNullOrEmpty(context.Request.Headers["X-Real-IP"].ToString()) ? context.Connection.RemoteIpAddress.MapToIPv4().ToString() : context.Request.Headers["X-Real-IP"].ToString(),
                ForwardIp = string.IsNullOrEmpty(context.Request.Headers["X-Forwarded-For"].ToString()) ? context.Connection.RemoteIpAddress.MapToIPv4().ToString() : context.Request.Headers["X-Forwarded-For"].ToString(),
                Referer = context.Request.Headers["Referer"].ToString(),
                Url = context.Request.Path.ToString()
            };
            db.Add(log);
            await db.SaveChangesAsync();
        }
        await _next(context);
    }
}

需要注意的有几点:

  • 需要注入 DbContext 来实现保存到数据库
  • 需要注入 Configuration 来判断需要记录的类型
  • 对于使用了反向代理,需要手动判断请求头中的 X-Forawarded-ForX-Real-IP两个头来确定IP地址(尽管有 ForwardedHeadersOptions 可供使用,但对于静态文件来说,还没有到 ForwardedHeadersOptions 处理就已经返回响应了)

然后再 Srartup 里使用该中间件即可,最好把该中间件放到请求最开始的位置。

app.UseMiddleware<AccessLogMiddleWare>();
发布时间:2021-04-28
其他阅读

我的读书清单

分享互联网人的读书清单,从2024年开始,本文会整理我读过的书籍,按时间排序,编辑成一份读书清单。

查看原文

Web前端中实现一个拖动效果

在原生客户端开发中,窗口拖动是一个比较常用的操作。今天把这个效果在网页客户端中实现以下,文章记录一下效果。

查看原文

浅析web前端中的MVC模式

MVC是常见的软件架构设计模式,它通过分离关注点改进代码的组织方式。区别于软件设计模式,只是为了解决问题总结出的抽象方法,一种架构模式种往往会用到多种设计模式。

查看原文

IIS 设置跨域问题

之前说过nginx设置跨域,今天记录以下IIS设置跨域

查看原文

使用C#接入DeepSeek API实现自己的AI助手

过年期间DeepSeek非常火爆,这段时间用着官方的客户端访问,总是会提示“服务器繁忙,请稍后再试。”,本文介绍怎么通过接入DeepSeek的API实现自己的客户端。

查看原文