ASP.NET Core 记录请求日志

在 ASP.NET Core 应用程序中,记录请求日志可以帮助开发者分析请求情况、调试错误以及监控应用的运行状态。本文介绍如何通过配置 Logging 记录请求日志。

配置 appsettings.json 记录请求日志

在 appsettings.json 文件的 Logging 配置中,添加或修改以下内容:

"Logging": {
  "LogLevel": {
    "Default": "Information",
    "Microsoft": "Warning",
    "Microsoft.Hosting.Lifetime": "Information",
    // 下面两行用于记录请求日志
    "Microsoft.AspNetCore.Hosting.Diagnostics": "Information",
    "Microsoft.AspNetCore.Server.Kestrel": "Information"
  }
}

如果你的 appsettings.json 文件中已经有 Logging 配置,只需添加以下两行:

"Microsoft.AspNetCore.Hosting.Diagnostics": "Information",
"Microsoft.AspNetCore.Server.Kestrel": "Information"

说明

Microsoft.AspNetCore.Server.Kestrel:记录 Kestrel 服务器的详细请求信息,例如请求地址、请求头、响应状态等。

Microsoft.AspNetCore.Hosting.Diagnostics:记录 ASP.NET Core 请求处理的相关日志,包括中间件执行等。

运行应用并查看日志

如果你的应用使用 控制台日志 或 文件日志,可以在终端或日志文件中查看请求日志。例如,运行应用后,在控制台中可能会看到类似的日志输出:

info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/1.1 GET http://localhost:5000/  
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 25ms 200 application/json  

如果你希望将日志输出到文件,可以在 appsettings.json 中进一步配置日志提供程序,例如使用 Serilog 或 NLog 进行日志存储和分析。

Debian使用服务单元部署asp.net core

创建 /etc/systemd/system/your_app.service 文件,替换为适合你的应用的名称:

[Unit]
Description=ASP.NET Core Application

[Service]
WorkingDirectory=/path/to/your_app/publish
ExecStart=/usr/bin/dotnet /path/to/your_app/publish/your_app.dll
Restart=always
RestartSec=10
SyslogIdentifier=dotnet-your_app
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target
  • WorkingDirectory:应用程序的工作目录(发布目录)。
  • ExecStart:启动应用的命令,这里指定 dotnet 和应用的 DLL 文件路径。
  • Restart:配置应用异常退出时自动重启。
  • SyslogIdentifier:指定日志标识符,可以方便地过滤日志。
  • User:指定运行服务的用户(例如 www-data,避免使用 root 用户)。
  • Environment:指定环境变量(如 Production)。

启动并启用服务:

sudo systemctl enable your_app.service
sudo systemctl start your_app.service

查看服务状态:

sudo systemctl status your_app.service

查看服务日志:

sudo journalctl -u your_app.service

nginx 反代模板:

server {
    listen 80;
    server_name your_domain.com;

    location / {
        proxy_pass https://notes.wujie.me:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

查看实时日志输出

要实时查看应用的日志输出,可以使用以下命令:

sudo journalctl -u your_app.service -f
  • -u your_app.service 指定服务名称,替换为你的服务文件名称。
  • -f 表示实时跟踪日志输出(类似 tail -f)。

查看全部日志

查看应用自启动以来的全部日志:

sudo journalctl -u your_app.service

这将显示该服务的全部日志记录。

按时间范围查看日志

可以按时间范围筛选日志,例如查看过去一小时的日志:

sudo journalctl -u your_app.service --since "1 hour ago"

或者查看特定日期之后的日志:

sudo journalctl -u your_app.service --since "2024-11-01"

按关键字过滤日志

如果你只想查看特定关键字的日志,例如包含错误信息的日志,可以使用 grep 命令进行过滤:

sudo journalctl -u your_app.service | grep "error"

 清除指定服务的日志

要清除特定服务(如 ASP.NET Core 应用)的日志,可以使用 journalctl 的 –vacuum 选项。虽然 journalctl 没有直接提供按服务清除的功能,但可以通过指定服务名来筛选日志,再结合清除命令:

sudo journalctl --vacuum-size=100M -u your_app.service

这将限制日志文件的总大小为 100MB,多余的日志会被删除。将 100M 替换为你期望的日志限制大小。

清除日志到指定时间点

你可以通过 –vacuum-time 参数清除指定时间之前的所有日志数据:

sudo journalctl --vacuum-time=7d

这将清除 7 天之前的所有日志数据,包括所有服务的日志(不是仅 ASP.NET Core 应用)。

清除所有 journald 日志

如果你希望彻底清除所有 journald 日志数据(适用于开发或测试环境,生产环境需谨慎),可以使用以下命令:

sudo journalctl --vacuum-size=1M

这会将日志数据限制为 1MB,基本相当于清空所有日志数据。

如果你希望彻底清除所有 journald 日志数据(适用于开发或测试环境,生产环境需谨慎),可以使用以下命令:

sudo journalctl –vacuum-size=1M

删除 journal 日志文件

可以手动删除存储在 /var/log/journal/ 目录下的日志文件。这样会清空所有服务的日志,建议谨慎使用。

sudo rm -rf /var/log/journal/*
sudo systemctl restart systemd-journald

定期清理

可以在 journald 配置文件 /etc/systemd/journald.conf 中设置日志的最大保留大小或时间,定期清理旧日志。

C# 判断中文、日文和韩文

在 C# 中,我们可以使用正则表达式来判断字符串是否包含特定的字符集。本文将展示如何使用正则表达式来判断字符串是否为中文、日文或韩文。

1. 正则表达式简介

  • 中文字符:匹配 Unicode 范围为 \u4e00-\u9fa5 的字符。
  • 日文字符:匹配 Unicode 范围为 \u3040-\u309F(平假名)、\u30A0-\u30FF(片假名)、\u4E00-\u9FFF(常用汉字)。
  • 韩文字符:匹配 Unicode 范围为 \uac00-\ud7ff 的字符。

2. 匹配东亚语言

如果要匹配所有东亚语言(包括中文、日文和韩文),可以使用如下的正则表达式:

// language: csharp
@"[\u4E00-\u9fa5\u3040-\u309F\u30A0-\u30FF\uac00-\ud7ff]"

该正则表达式能够匹配中文、日文和韩文字符,但如果你希望对不同语言进行分类,则需要具体判断。

3. 判断韩文

要判断字符串是否为韩文,可以使用以下代码:

// language: csharp
if(System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\uac00-\ud7ff]+$"))
{
    // 如果是韩文
}

该正则表达式会检查字符串是否仅包含韩文字符。

4. 判断日文

判断字符串是否为日文,代码如下:

// language: csharp
if(System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]+$"))
{
    // 如果是日文
}

该正则表达式会检查字符串是否仅包含日文字符。

5. 判断中文

判断字符串是否为中文字符,可以使用以下代码:

// language: csharp
if (System.Text.RegularExpressions.Regex.IsMatch(content, @"^[\u4e00-\u9fa5]+$"))
{
    // 如果是中文
}

该正则表达式会检查字符串是否仅包含中文字符。

6. 示例应用

通过结合正则表达式,我们可以很方便地在 C# 中进行不同语言的文本检测。以下是完整示例代码:

// language: csharp
using System;
using System.Text.RegularExpressions;

public class LanguageDetection
{
    public static void Main(string[] args)
    {
        string content = "这是一个测试内容";

        // 判断是否为中文
        if (Regex.IsMatch(content, @"^[\u4e00-\u9fa5]+$"))
        {
            Console.WriteLine("这是中文");
        }
        // 判断是否为日文
        else if (Regex.IsMatch(content, @"^[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]+$"))
        {
            Console.WriteLine("这是日文");
        }
        // 判断是否为韩文
        else if (Regex.IsMatch(content, @"^[\uac00-\ud7ff]+$"))
        {
            Console.WriteLine("这是韩文");
        }
        else
        {
            Console.WriteLine("无法识别的语言");
        }
    }
}

这段代码会根据内容的语言输出相应的结果。

.NET中如何使用PhantomJS与Selenium模拟采集数据

在现代 web 开发中,数据采集是一个非常常见的需求。无论是从网站中提取信息,还是进行自动化测试,模拟用户行为都变得尤为重要。在 .NET 环境中,常见的两种模拟采集的工具是 PhantomJS 和 Selenium。这两者各具特点,适用于不同的场景。本文将介绍这两款工具及其如何在 .NET 中使用。

1. PhantomJS——无头浏览器的利器

什么是 PhantomJS?

PhantomJS 是一个无头浏览器(headless browser),意味着它没有图形界面,完全通过命令行操作。它可以模拟浏览器行为,执行网页中的 JavaScript 代码,获取渲染后的网页内容,并支持截图、页面交互等操作。由于它不需要图形界面,运行效率比普通浏览器更高,尤其适用于大规模的网页抓取和自动化测试。

PhantomJS 在数据采集中的应用

PhantomJS 非常适合用来进行 网页抓取,特别是当页面内容通过 JavaScript 动态生成时。很多现代网站的数据展示依赖于 JavaScript 渲染,传统的 HTML 解析工具(如 HtmlAgilityPack)在这种情况下无法直接提取数据,而 PhantomJS 可以通过模拟浏览器,渲染页面并抓取其中的数据。

在 .NET 中使用 PhantomJS

虽然 PhantomJS 自身是用 JavaScript 编写的,但我们可以通过使用外部库来在 .NET 中调用 PhantomJS。一个常用的库是 PhantomJS.Net,它提供了 .NET 与 PhantomJS 的接口,使得在 .NET 中模拟浏览器变得更加方便。

使用 PhantomJS.NET 的示例代码:

// language: csharp
using System;
using PhantomJS.Net;

class Program
{
    static void Main()
    {
        var driver = new PhantomJSDriver();
        driver.Navigate().GoToUrl("https://example.com");

        // 获取渲染后的网页内容
        var pageSource = driver.PageSource;
        Console.WriteLine(pageSource);

        driver.Quit();
    }
}

在这个示例中,我们首先初始化了一个 PhantomJS 驱动器,加载了目标网页,然后获取了渲染后的 HTML 内容。

2. Selenium——强大的自动化测试工具

什么是 Selenium?

Selenium 是一款广泛使用的自动化测试工具,支持多种编程语言(包括 C#、Java、Python 等)。它不仅可以用来模拟浏览器行为,还支持模拟用户操作,如点击、输入、滚动等。Selenium 支持所有现代浏览器,包括 Chrome、Firefox 和 Safari 等,除了无头浏览器模式(headless mode)外,它还支持在有图形界面的环境下操作浏览器。

Selenium 在数据采集中的应用

Selenium 可以模拟真实的用户行为,因此非常适合 交互式数据采集。例如,你需要登录网站、填写表单、点击按钮来获取数据时,Selenium 是一个理想的选择。而且它支持 JavaScript 执行,因此可以抓取动态加载的网页内容。

在 .NET 中使用 Selenium

在 .NET 环境中使用 Selenium 需要安装相应的 NuGet 包。常见的库有 Selenium.WebDriver 和 Selenium.WebDriver.ChromeDriver,这些包可以通过 NuGet 安装。

使用 Selenium 的示例代码:

// language: csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;

class Program
{
    static void Main()
    {
        // 设置 Chrome 驱动器
        var options = new ChromeOptions();
        options.AddArgument("headless"); // 无头模式

        var driver = new ChromeDriver(options);
        driver.Navigate().GoToUrl("https://example.com");

        // 获取渲染后的网页内容
        var pageSource = driver.PageSource;
        Console.WriteLine(pageSource);

        driver.Quit();
    }
}

这个示例展示了如何通过 Selenium 在无头模式下启动 Chrome 浏览器,加载目标网页,并获取渲染后的 HTML 内容。

3. PhantomJS 与 Selenium 的对比

虽然 PhantomJS 和 Selenium 都可以用来模拟采集,但它们有一些显著的区别:

特性PhantomJSSelenium
浏览器类型无头浏览器 (Headless Browser)可以支持有头和无头浏览器
性能高效,启动速度快,适合大规模抓取启动速度稍慢,但更强大、灵活
JavaScript 支持完全支持 JavaScript完全支持 JavaScript
支持的浏览器仅 PhantomJS支持所有主要浏览器(Chrome, Firefox, Safari)
适用场景爬虫和抓取静态页面自动化测试和交互式爬虫

从对比表格中可以看出,PhantomJS 更适合于快速的网页抓取,尤其是当你只需要获取页面内容而不需要模拟用户交互时。而 Selenium 更适合需要复杂交互的场景,如登录、填写表单、点击按钮等。

4. 总结

PhantomJS 和 Selenium 都是强大的工具,能够帮助开发者在 .NET 中模拟浏览器行为进行数据采集。选择哪个工具取决于你的需求:

  • 如果你需要快速抓取页面并且不需要复杂的用户交互,PhantomJS 是一个不错的选择。
  • 如果你需要模拟更复杂的用户行为(如填写表单、点击按钮等),Selenium 会更为适合。

无论你选择哪个工具,正确使用它们将能帮助你高效地进行数据采集工作。

ASP.NET Core 中如何获取 Unix 时间戳

在 ASP.NET Core 中,我们可以通过 DateTimeOffset 类型来获取当前时间的 Unix 时间戳。DateTimeOffset 代表一个带有时区偏移量的日期和时间,它提供了比 DateTime 更强大的时区支持。要获取当前时间的 Unix 时间戳,可以使用 ToUnixTimeSeconds 方法。

需要注意的是,此方法从 .NET Core 2.0 开始提供。

1. 获取当前时间的 Unix 时间戳

// language: csharp
using System;

public class Program
{
    public static void Main()
    {
        // 获取当前时间的 Unix 时间戳(秒级)
        long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
        Console.WriteLine("当前时间的 Unix 时间戳为: " + timestamp);
    }
}

2. 获取 UTC 时间的 Unix 时间戳

如果你需要获取 UTC 时间的 Unix 时间戳,可以使用 DateTimeOffset.UtcNow,它返回的是 UTC(协调世界时)时间。

// language: csharp
using System;

public class Program
{
    public static void Main()
    {
        // 获取当前 UTC 时间的 Unix 时间戳(秒级)
        long timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        Console.WriteLine("当前 UTC 时间的 Unix 时间戳为: " + timestamp);
    }
}

C#数据库连接类

在使用ado.net连接数据库时,我们需要自己创建数据库连接类,目的是为了方便对数据库连接进行管理和方便使用。下面的Db类用于创建并打开一个数据库连接。

这个类也可以搭配Dapper使用,当使用Dapper时,我们也需要这样的一个类,使用使用conn来调用Dapper中的一些扩展方法用于快速操作数据库。

public class Db
{
	private static string connectionString = "Data Source=.;Initial Catalog=Minsu;User Id=sa;Password=123456;Encrypt=False;TrustServerCertificate=False;";

	public static SqlConnection GetConnection()
	{
		SqlConnection conn = new SqlConnection(connectionString);
		conn.Open();
		return conn;
	}
}

这个类在使用时,记得要放在using中使用,以避免资源泄露。例如下面的代码:

using(var conn = Db.GetConnection()) 
{
    // 数据库操作...
}

解决 ASP.NET Core 连接 SQL Server 时“证书链由不受信任的颁发机构颁发”错误

使用基于.NET 8的ASP.NET Core连接sql server数据库时,遇到报错:sql server 证书链是由不受信任 的颁发机构颁发的

解决办法是,在数据库连接串上增加TrustServerCertificate=False;,即改为下面的形式就可以了:

// language: csharp
Data Source=.;Initial Catalog=WorkSummary;User Id=sa;Password=123456;Encrypt=False;TrustServerCertificate=False;

EntityFramework DbFirst

EntityFramework这个.NET 的 ORM框架,可以代码优先(code first),也可以数据库优先(database first),本文主要介绍数据库优先 database first 的使用方法:

先在Package Manager Console中安装 Microsoft.EntityFrameworkCore.Tools包:

Install-Package Microsoft.EntityFrameworkCore.Tools

然后使用下面的命令扫描数据库,该命令根据数据库连接串扫描数据库,并生成相应的模型类。

Scaffold-DbContext "Server=127.0.0.1;User ID=root;Password=123456;Database=worksummary_net;" Pomelo.EntityFrameworkCore.MySql -OutputDir Data\Entities

扫描完成后,就可以在项目中使用EF进行数据库操作了。

C# 字典Dictionary.Add(key, value) 与 Dictionary[key]=value的区别

相同:

二者都是根据键值(key),在字典中添加新元素(value)的方法

不同:

Dictionary.Add(key, value) 方法,如果 Dictionary 中已经有了这个 key ,那么在进行 Add 会在运行时报错;

Dictionary[key]=value 方法,如果 Dictionary 中已经有了这个key ,新添加的value将替换之前的 value ,即没有时添加,有时则修改替换

因此,在使用时更加倾向使用 Dictionary[key]=value 方法,可以减少出错,但是使用时也要注意键值是否正确对应。