• Web应用程序,简单的日志系统解决方案


    一、简介

    今天介绍一下,当你的程序没有日志系统时,如何快速方便查看当前程序日志的解决方案。如果你的程序有日志系统,可以不看本篇博客哈。本文实例是使用 C# 讲解,当然实现的核心思想适用于其他语言开发的系统。

    二、解决方案

    这里介绍 DotNet Core 与 DotNet Framework 两种平台的解决方案,这里只讲了核心代码,实际使用可以根据自己的实际情况,加一些限制或者安全效验。

    2.1 DotNet Core

    如下,新建一个 CustomerService 程序,日志在项目的 Logs 文件夹下
    在这里插入图片描述

    2.1.1 日志列表

    创建一个 LogController Web API,并创建一个 FileList 的 API,这个 API 主要读取日志文件列表,并拼接成 HTML 返回给浏览器

    [ApiController]
    [Route("[controller]")]
    public class LogController : ControllerBase
    {
        private readonly string _logPath = "Logs";
    
        [HttpGet]
        [Route(nameof(FileList))]
        public async Task FileList()
        {
            string path = Directory.GetCurrentDirectory() + $"\\{_logPath}";
            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            var files = directoryInfo?.GetFiles()?.OrderByDescending(x => x.LastWriteTime);
            if (files == null)
            {
                string msg = "not log file";
                var msgBytes = Encoding.UTF8.GetBytes(msg);
                Response.ContentType = "text/plain";
                await Response.Body.WriteAsync(msgBytes, 0, msgBytes.Length);
            }
            else
            {
                StringBuilder html = new StringBuilder();
                foreach (var file in files)
                {
                    html.AppendLine($"

    {file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")}  {_logPath}\\{file.Name}\">{file.Name}  {file.Length / 1048576.0000} MB

    "
    ); } var htmlBytes = Encoding.UTF8.GetBytes(html.ToString()); Response.ContentType = "text/html"; await Response.Body.WriteAsync(htmlBytes, 0, htmlBytes.Length); } } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    如下,是 FileList API 接口返回的结果,列出来的日志文列表,并给予文件名称超链接,如下
    在这里插入图片描述

    2.1.2 日志内容

    创建一个新的 FileContent API,这个 API 实现的是 “文件名称超链接” 部分的功能,主要读取指定的日志文件内容,并返回给浏览器

            [HttpGet]
            [Route(nameof(FileContent))]
            public async Task FileContent(string filePath)
            {
                filePath = Directory.GetCurrentDirectory() + filePath;
                string fileContent = string.Empty;
                using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var sr = new StreamReader(fs, Encoding.UTF8))
                    {
                        fileContent = sr?.ReadToEnd();
                    }
                }
    
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"MachineName:{Environment.MachineName} | OSVersion:{Environment.OSVersion.ToString()} \r\n");
                var lines = fileContent.Split(new char[2] { '\r', '\n' });
                int index = lines.Length - 1;
                while (index >= 0)
                {
                    if (!string.IsNullOrWhiteSpace(lines[index]))
                        sb.AppendLine(lines[index]);
                    index -= 1;
                }
                string sbStr = sb.ToString();
    
                var htmlBytes = Encoding.UTF8.GetBytes(sbStr);
                Response.ContentType = "text/plain";
                await Response.Body.WriteAsync(htmlBytes, 0, htmlBytes.Length);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    如下,FileContent API 返回了一个 txt 日志文件的内容,这里随便模拟日志写了点文本
    在这里插入图片描述

    2.2 DotNet Framework

    前面讲了 DotNet Core 为什么还要说下 DotNet Framework 呢,因为两个平台的一些实现 API 不一样,但实现思路与核心都是一样的。

    如下,新建一个 OrderService 程序,日志在项目的 App_Data\Logs 文件夹下
    在这里插入图片描述

    2.2.1 日志列表

    创建一个 LogController Web API,并创建一个 FileList 的 API,这个 API 主要读取日志文件列表,并拼接成 HTML 返回给浏览器

    [RoutePrefix("Log")]
    public class LogController : ApiController
    {
        private readonly string _logPath = "App_Data\\Logs";
    
        [HttpGet]
        [Route(nameof(FileList))]
        public HttpResponseMessage FileList()
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK);
    
            string path = HostingEnvironment.MapPath(@"~/") + _logPath;
            DirectoryInfo directoryInfo = new DirectoryInfo(path);
            var files = directoryInfo?.GetFiles()?.OrderByDescending(x => x.LastWriteTime);
            if (files == null)
            {
                response.Content = new StringContent("not log file", Encoding.UTF8, "text/plain");
                return response;
            }
    
            StringBuilder html = new StringBuilder();
            foreach (var file in files)
            {
                html.AppendLine($"

    {file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")}  {_logPath}\\{file.Name}\">{file.Name}  {file.Length / 1048576.0000} MB

    "
    ); } response.Content = new StringContent(html.ToString(), Encoding.UTF8, "text/html"); return response; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    如下,是 FileList API 接口返回的结果,列出来的日志文列表,并给予文件名称超链接,如下
    在这里插入图片描述

    2.2.2 日志内容

    创建一个新的 FileContent API,这个 API 实现的是 “文件名称超链接” 部分的功能,主要读取指定的日志文件内容,并返回给浏览器

            [HttpGet]
            [Route(nameof(FileContent))]
            public HttpResponseMessage FileContent(string filePath)
            {
                filePath = HostingEnvironment.MapPath(@"~/") + filePath;
                string content = string.Empty;
                using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var sr = new StreamReader(fs, Encoding.UTF8))
                    {
                        content = sr?.ReadToEnd();
                    }
                }
    
                StringBuilder sb = new StringBuilder();
                sb.AppendLine($"MachineName:{Environment.MachineName} | OSVersion:{Environment.OSVersion.ToString()} \r\n");
                var lines = content.Split(new char[2] { '\r', '\n' });
                int index = lines.Length - 1;
                while (index >= 0)
                {
                    if (!string.IsNullOrWhiteSpace(lines[index]))
                        sb.AppendLine(lines[index]);
                    index -= 1;
                }
                string sbStr = sb.ToString();
    
                var response = new HttpResponseMessage(HttpStatusCode.OK);
                response.Content = new StringContent(sbStr, Encoding.UTF8, "text/plain");
                return response;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    如下,FileContent API 返回了一个 txt 日志文件的内容,这里随便模拟日志写了点文本
    在这里插入图片描述

    四、源码

    下面连接,包含了 DotNet Core 与 DotNet Framework 实现日志解决方案的全部代码,需要的自行下载
    https://download.csdn.net/download/weixin_46785144/87235310

  • 相关阅读:
    Monkey测试
    实用工具系列 - FileZilla安装下载与使用
    Redis GEO 类型与 API 结合,地理位置优化的绝佳实践
    下海建龙宫
    【云原生】Docker可视化监控管理工具使用
    类似火车头的采集器-免费任意数据采集器
    Qt的模型与视图
    OpenGL ES EGL 名词解释
    时序数据库-5-[IoTDB]的数据迁移
    百度OCR 接口调用 提示 216101:param image not exist 问题解决
  • 原文地址:https://blog.csdn.net/weixin_46785144/article/details/128155760