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

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

HTTP方法

HTTP报文中包含了方法,指的是客户端希望服务器对资源执行的动作,是一个单独的词,比如GET,POST,OPTIONS等,本文将会介绍主流的几种方法。

查看原文

命令行打包.net项目

.net 日常开发中,我们接触最多的就是 Visual Studio ,它是微软为了 .net 平台专门打造的 IDE (集成开发环境),为整个 .net 平台开发带来了无与伦比的图形化体验,但是有时候,我们也会遇到需要通过命令行来生成 .net 项目的情况,本文会介绍几种命令行打包的姿势。

查看原文

管道技术——中间件的灵魂

在现代Web开发中,中间件技术使用越来越广泛,本文带大家了解中间件的基础,同时也是中间件的灵魂所在,管道技术。在C#中,依赖于委托,我们可以很容易就实现一个中间件管道。所以在阅读本文前,请确保你已经学会了什么是委托,包括但不限于Delegate,Action,Func。除此之外,本文还会使用到反射相关知识,请确保你已经学会了什么是反射。

查看原文

Windows的刘海生成器

其实是很早之前在论坛讨论当时苹果率先推出了带刘海的 mac book pro 的时候,就花了几分钟做了一个模拟刘海的软件,可以给 Windows 系统加上刘海。

查看原文

WPF中切换主题功能

在现代 Windows 系统中,系统提供了亮色主题和暗色主题,Windows 自带的应用程序都已经适配该功能。本文介绍在使用 WPF 构建 Windows 窗口应用时怎么实现主题切换。

查看原文