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

对于网站访问日志的记录,一般情况下都是使用现有的日志服务,比如谷歌分析引入轻量 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
其他阅读

Open Graph优化SEO

Open Graph(OG)协议作为社交分享优化的核心技术,不仅决定了内容在社交媒体平台的展示效果,还间接影响搜索引擎优化(SEO)的表现。本文将从作用解析、核心标签配置到动态生成策略,全面介绍 Open Graph 的应用。

查看原文

解决ssh登录后闲置一段时间断开

最新新买了一台服务器,使用 ssh 登录之后发现一段时间没有输入就会自动断开,这里记录一下解决方法。

查看原文

HTTP状态码

HTTP状态码为客户端提供了一种理解事务处理结果的边界方式。本文列出一些原因短语,所使用的是HTTP/1.1规范所定义的。

查看原文

个人简介

你好,我是猪头少年,是一名定居在云南的软件工程师,主要的开发语言为 C#JavaScript,涉及 ASP.NET CoreWPFAngularUnity 以及 Babylon.js。平时喜欢自驾出游。欢迎大家联系我。

查看原文

扩展Serilog实现日志推送平台

最近在完成一个服务管理平台,提供可视化管理车间控制服务,包括服务的启停,日志的查看。在各服务中使用 Serilog 对日志进行记录,推送到服务管理平台,再进行统一分发,各客户端同步查看服务运行日志。

查看原文