log4c库使用

log4c库

介绍

log4c 是一个 C 语言实现的日志库,它是 log4j(Java 语言的日志框架)的 C 语言版本,旨在为 C 语言应用程序提供灵活、可配置的日志功能。log4c 提供了丰富的日志功能,包括日志级别、日志输出目标、日志格式等,支持不同的日志策略,比如滚动文件、按大小或按日期滚动等,具有良好的可扩展性和配置能力

安装

解压安装

下载链接
https://sourceforge.net/projects/log4c/files/log4c/1.2.4/log4c-1.2.4.tar.gz/download?use_mirror=onboardcloud&login=from_csdn

tar -zxvf log4c-1.2.4.tar.gz
cd log4c-1.2.4
./configure --prefix=/usr/local/log4c # 必须明确指定安装路径
make
make install

注意
--prefix 必须明确指定安装路径
/usr/local/log4c 这个是系统路径,安装完了之后就可以直接使用,不需要指明头文件位置
如果安装到其他位置,再执行完make install 之后会出现在指定的目录下,使用的时候需要指明头文件位置;

apt安装

sudo apt update
sudo apt install liblog4c-dev

使用方式

cmake 文件编写

apt安装
# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 指定项目名称和语言
project(kylin-wine-starter VERSION 1.0 LANGUAGES C)

# 设置 C 编译器标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

# 自动查找所有的 .c 文件
file(GLOB SOURCES "*.c")

# 定义可执行文件的名称和源文件
add_executable(${PROJECT_NAME} ${SOURCES})

pkg_check_modules(LOG4C REQUIRED log4c)

include_directories(${LOG4C_INCLUDE_DIRS})
link_directories(${LOG4C_LIBRARY_DIRS})

target_link_libraries(${PROJECT_NAME} ${LOG4C_LIBRARIES})
解压安装

请添加图片描述
此处展示的文件结构是本篇文章演示的文件结构

# 指定 CMake 的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 指定项目名称和语言
project(kylin-wine-starter VERSION 1.0 LANGUAGES C)

# 设置 C 编译器标准
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)

# 自动查找所有的 .c 文件
file(GLOB SOURCES "*.c")

# 定义可执行文件的名称和源文件
add_executable(${PROJECT_NAME} ${SOURCES})

set(3RDLIB_PATH ${PROJECT_SOURCE_DIR}/third)  
list(APPEND 3RD_LIBS_INCLUDE "${3RDLIB_PATH}/include")  
list(APPEND 3RD_LIBS_INCLUDE "${3RDLIB_PATH}/include/log4c") 
link_directories("${3RDLIB_PATH}/lib")  
target_link_libraries(${PROJECT_NAME} log4c)   
# link_libraries(log4c)   # 禁止使用这种链接方式
target_include_directories(${PROJECT_NAME} PUBLIC   
    ${PROJECT_BINARY_DIR}   
    ${EXTRA_INCLUDE}   
    ${3RD_LIBS_INCLUDE}  
)

配置输出位置以及轮转策略

log4c使用结构图
在这里插入图片描述
创建一个category管理多个appender,
每个appender都是一个文件,
每个appender中都有一个layout,
每个layout都规定了日志文件中输出的格式;
每个appender都可以设置轮转格式,
需要给appender指定一个轮转文件rollingfile,
给rollingfile指定一个轮转策略rolling_policy,
给rolling_policy 指定一个限制文件大小rolling_sizewin。
这样就能实现通过文件大小进行轮转了

配置文件
  1. 配置文件使用xml格式,默认在当前工作目录下找;默认找到是log4crc(不带扩展名),如果有扩展名(log4crc.xml)需要特别配置环境变量
  2. LOG4C_RCPATH 配置环境变量
  3. 优先找工作目录配置文件,再通过环境变量找配置文件;只要找到了就会停下来,不论这个配置文件是对是错
    配置文件category,appender,rollingpolicy,layout 的相互关系是通过name来相互绑定的
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE log4c SYSTEM "">

<log4c version="1.2.4">

	<config>
		<bufsize>0</bufsize>
		<debug level="2"/>
		<nocleanup>0</nocleanup>
		<reread>1</reread>
	</config>
    <category name="root" priority="error" appender="stdout"/>
	<appender name="stdout" type="stream" layout="basic"/>
	<appender name="stderr" type="stream" layout="dated"/>
	<appender name="syslog" type="syslog" layout="basic"/>
	<layout name="basic" type="basic"/>
	<layout name="dated" type="dated"/>
</log4c>
log4c_init();// 初始化
// 代码中也是通过配置文件中的name进行获取的
log4c_category_t* mycat = log4c_category_get("root"); 
log4c_category_log(mycat,LOG4C_PRIORITY_DEBUG,"输出内容");
log4c_fini();// 销毁
layout 日志输出格式

<layout name="basic" type="basic"/> 这里的type可以替换为下面库里面提供的这些

// layout
const log4c_layout_type_t log4c_layout_type_basic = {
    "basic",// 布局名称,可以替换到layout的type位置
    basic_format,// 布局函数,可以在接下来介绍的API部分为layout设置type
};
const log4c_layout_type_t log4c_layout_type_basic_r = {
    "basic_r",
    basic_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local_r = {
    "dated_local_r",
    dated_local_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local = {
    "dated_local",
    dated_local_format,
};
const log4c_layout_type_t log4c_layout_type_dated_r = {
    "dated_r",
    dated_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated = {
    "dated",
    dated_format,
};
appender 日志文件

<appender name="myrollingfileappender" type="rollingfile" logdir="." prefix="myprefix" layout="dated_time" rollingpolicy="myrollingpolicy" />
使用下面字符串中的内容替换 type

// 将日志信息写入内存映射文件(mmap)。内存映射文件是操作系统提供的一种将文件或设备映射到内存中的技术,允许程序像操作内存一样操作文件。
const log4c_appender_type_t log4c_appender_type_mmap = {
    "mmap",
    mmap_open,
    mmap_append,
    mmap_close,
};
// 将日志信息写入到文件中,并在日志文件大小达到一定限制时自动进行轮转(即生成新的日志文件)
const log4c_appender_type_t log4c_appender_type_rollingfile = {
    "rollingfile",
    rollingfile_open,
    rollingfile_append,
    rollingfile_close
};
// 将日志信息输出到一个流(如标准输出流、文件流等)。这种方式适用于将日志输出到控制台或文件等流设备。
const log4c_appender_type_t log4c_appender_type_stream = {
    "stream",
    stream_open,
    stream_append,
    stream_close,
};
// 这应该是 stream 的另一种实现,可能有不同的实现或配置,用于特殊场景。
const log4c_appender_type_t log4c_appender_type_stream2 = {
    "stream2",
    stream2_open,
    stream2_append,
    stream2_close,
};
// 将日志信息发送到操作系统的系统日志(通常是 syslog)。适用于需要将日志信息传递给系统日志守护进程进行集中管理的场景。
const log4c_appender_type_t log4c_appender_type_syslog = {
    "syslog",
    syslog_open,
    syslog_append,
    syslog_close,
};

logdir="." 当 type 为rollingfile 的时候设置日志存储位置
prefix="myprefix"当 type 为rollingfile 的时候设置日志的前缀,通常轮转之后的文件是prefix.数字
rollingpolicy 指的是轮转策略
<rollingpolicy name="myrollingpolicy" type="sizewin" maxsize="1024" maxnum="3" />
库中只提供了一种通过文件大小进行轮转的策略
maxsize 表示每个文件最大容量
maxnum 轮转过程中保存最近3个文件

const log4c_rollingpolicy_type_t log4c_rollingpolicy_type_sizewin = {
    "sizewin", // 写入 type 位置
    sizewin_init,
    sizewin_is_triggering_event,
    sizewin_rollover,
    sizewin_fini
};
catgory 用来管理appender

<category name="root" priority="error" appender="stdout"/> priority 可以替换为下面的这些, 将下面注释中的字符串进行替换

// priority —— 输出等级,值越小的等级越高
 typedef enum {

    /** fatal */	LOG4C_PRIORITY_FATAL	= 000, 
    /** alert */	LOG4C_PRIORITY_ALERT	= 100, 
    /** crit */	      	LOG4C_PRIORITY_CRIT	= 200, 
    /** error */	LOG4C_PRIORITY_ERROR	= 300, 
    /** warn */	      	LOG4C_PRIORITY_WARN	= 400, 
    /** notice */	LOG4C_PRIORITY_NOTICE	= 500, 
    /** info */	      	LOG4C_PRIORITY_INFO	= 600, 
    /** debug */	LOG4C_PRIORITY_DEBUG	= 700,
    /** trace */	LOG4C_PRIORITY_TRACE	= 800,
    /** notset */	LOG4C_PRIORITY_NOTSET	= 900,
    /** unknown */	LOG4C_PRIORITY_UNKNOWN	= 1000
} log4c_priority_level_t;
直接API

一般情况下只需要引用 log4c.h 这个头文件就可以了,不需要像我下面这样一个一个的列出来,如果在使用的时候发现没有再添加引用就可以了
安装到系统中,头文件引用方式如下

// #include "log4c.h"
// #include "log4c/appender.h"
// #include "log4c/appender_type_rollingfile.h"
// #include "log4c/rollingpolicy.h"
// #include "log4c/rollingpolicy_type_sizewin.h"
// #include "log4c/layout_type_dated.h"

未安装到系统中,头文件引用方式如下

#include "third/include/log4c.h"
#include "third/include/log4c/rc.h"
#include "third/include/log4c/appender.h"
#include "third/include/log4c/layout.h"
#include "third/include/log4c/category.h"
#include "third/include/log4c/appender_type_stream.h"
#include "third/include/log4c/appender_type_rollingfile.h"
#include "third/include/log4c/rollingpolicy.h"
#include "third/include/log4c/rollingpolicy_type_sizewin.h"
#include "third/include/log4c/layout_type_dated_local.h"
#include "third/include/log4c/layout_type_dated.h"
#include "third/include/log4c/layout_type_basic.h"
#include "third/include/log4c/priority.h"


log4c_category_t* mycat = NULL;
void create_log4c_API(char* dir,char* filename,long long size,int num){
	// log4c初始化
    if(log4c_init()){
        puts("497 log4c_init error");
        return;
    }
    // 创建category
    mycat = log4c_category_new(__FILE__);
    if(mycat == NULL){
        puts("mycat is NULL");
        return;
    }
    // 创建appender
    log4c_appender_t* appender = log4c_appender_new("myappender");
    if(appender == NULL){
        puts("appender is NULL");
        return;
    }
    // 设置appender类型
    log4c_appender_set_type(appender, &log4c_appender_type_rollingfile);// 文件轮转类型
	// 为category 设置 appender
    log4c_category_set_appender(mycat,appender);
	
	// 设置轮转的文件相关信息
    rollingfile_udata_t * rollingfile_udata = rollingfile_make_udata();
    // 设置目录
    rollingfile_udata_set_logdir(rollingfile_udata,dir);
    // 设置文件前缀
 rollingfile_udata_set_files_prefix(rollingfile_udata,filename);
	// 判断目录是否可写
    if(access(dir,W_OK) == -1){
        puts("no write permission");
        return;
    }

    // 配置文件滚动策略(基于文件大小滚动)
    log4c_rollingpolicy_t* rollingpolicy = log4c_rollingpolicy_new("sizewin");
    // 为文件设置滚动策略
rollingfile_udata_set_policy(rollingfile_udata,rollingpolicy);

    // 设置滚动策略参数
    rollingpolicy_sizewin_udata_t* swup = sizewin_make_udata();
    sizewin_udata_set_file_maxsize(swup, size);  // 每个日志文件最大大小为1MB
    sizewin_udata_set_max_num_files(swup, num);  // 最多保留5个文件
    // 为策略设置滚动策略参数
    log4c_rollingpolicy_set_udata(rollingpolicy,swup);
    // 初始化滚动策略
    int result = log4c_rollingpolicy_init(rollingpolicy, rollingfile_udata);
    if (result != 0) {
        // 处理错误
        puts("373 error");
        return;
    }
    // 设置附加器的滚动策略
    log4c_appender_set_udata(appender, rollingfile_udata);
    
	// 创建输出格式
    log4c_layout_t* mylayout = log4c_layout_new("mylayout");
    log4c_layout_set_type(mylayout,&log4c_layout_type_dated);
    // 为输出日志设置输出格式
    log4c_appender_set_layout(appender,mylayout);
	
	// 创建/打开日志文件,一般情况下是不需要明确的打开文件
	// 在验证日志没有正确的写入是不是因为没有打开文件造成的时候,可以使用这个函数排除错误
    // if(log4c_appender_open(appender) == 0){
    //     puts("537 file open success");
    // }else{
    //     puts("failed to open");
    // }
    // 输出必须要设置日志等级
    log4c_category_set_priority(mycat,LOG4C_PRIORITY_DEBUG);
    // 输出日志
    log4c_category_log(mycat,LOG4C_PRIORITY_INFO,"log4c_api 配置完成");
    // log4c 销毁
    log4c_fini();
}
log4c 创建和销毁
log4c_init(); // 创建
log4c_fini(); // 销毁
layout 日志输出格式
  1. log4c_layout_t* mylayout = log4c_layout_new("mylayout"); 创建layout
  2. log4c_layout_t* mylayout = log4c_layout_get("mylayout"); 从配置文件中获取namemylayout 的layout
  3. log4c_layout_set_type(mylayout,&log4c_layout_type_dated); 设置输出格式
// layout
const log4c_layout_type_t log4c_layout_type_basic = {
    "basic",
    basic_format, // 布局函数,替换到第二个参数
};
const log4c_layout_type_t log4c_layout_type_basic_r = {
    "basic_r",
    basic_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local_r = {
    "dated_local_r",
    dated_local_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated_local = {
    "dated_local",
    dated_local_format,
};
const log4c_layout_type_t log4c_layout_type_dated_r = {
    "dated_r",
    dated_r_format,
};
const log4c_layout_type_t log4c_layout_type_dated = {
    "dated",
    dated_format,
};
  1. log4c_appender_set_layout(appender,mylayout); 将layout绑定到appender上
appender 日志文件
  1. log4c_appender_t* appender = log4c_appender_new("myappender"); 创建
  2. log4c_appender_t* appender = log4c_appender_get("myappender"); 获取配置文件中namemyappenderappender
  3. log4c_appender_set_type(appender, &log4c_appender_type_rollingfile); 设置appender类型,下面的放到第二个参数的位置
// 将日志信息写入内存映射文件(mmap)。内存映射文件是操作系统提供的一种将文件或设备映射到内存中的技术,允许程序像操作内存一样操作文件。
const log4c_appender_type_t log4c_appender_type_mmap = {
    "mmap",
    mmap_open,
    mmap_append,
    mmap_close,
};
// 将日志信息写入到文件中,并在日志文件大小达到一定限制时自动进行轮转(即生成新的日志文件)
const log4c_appender_type_t log4c_appender_type_rollingfile = {
    "rollingfile",
    rollingfile_open,
    rollingfile_append,
    rollingfile_close
};
// 将日志信息输出到一个流(如标准输出流、文件流等)。这种方式适用于将日志输出到控制台或文件等流设备。
const log4c_appender_type_t log4c_appender_type_stream = {
    "stream",
    stream_open,
    stream_append,
    stream_close,
};
// 这应该是 stream 的另一种实现,可能有不同的实现或配置,用于特殊场景。
const log4c_appender_type_t log4c_appender_type_stream2 = {
    "stream2",
    stream2_open,
    stream2_append,
    stream2_close,
};
// 将日志信息发送到操作系统的系统日志(通常是 syslog)。适用于需要将日志信息传递给系统日志守护进程进行集中管理的场景。
const log4c_appender_type_t log4c_appender_type_syslog = {
    "syslog",
    syslog_open,
    syslog_append,
    syslog_close,
};
  1. rollingfile_udata_t * rollingfile_udata = rollingfile_make_udata(); 只能使用这种方式创建轮转的文件相关信息
  2. rollingfile_udata_set_logdir(rollingfile_udata,dir); 设置目录
  3. rollingfile_udata_set_files_prefix(rollingfile_udata,prefix); 设置文件前缀
  4. log4c_rollingpolicy_t* rollingpolicy = log4c_rollingpolicy_new("sizewin"); 配置文件滚动策略(基于文件大小滚动)
  5. rollingpolicy_sizewin_udata_t* swup = sizewin_make_udata(); 只能使用这种方式创建滚动策略参数
  6. sizewin_udata_set_file_maxsize(swup, size); 设置每个文件限定大小
  7. sizewin_udata_set_max_num_files(swup, num); 设置最多保留多少个轮转文件
  8. log4c_appender_set_layout(appender,mylayout); 为输出日志设置输出格式
  9. log4c_appender_set_udata(appender, rollingfile_udata); 设置附加器的滚动策略
  10. rollingfile_udata_set_policy(rollingfile_udata,rollingpolicy); 为文件设置滚动策略
  11. log4c_rollingpolicy_set_udata(rollingpolicy,swup); 为策略设置滚动策略参数
  12. log4c_rollingpolicy_init(rollingpolicy, rollingfile_udata); 初始化滚动策略
catgory 用来管理appender
  1. log4c_category_t* mycat = log4c_category_new("mycategory") 创建
  2. log4c_category_t* mycat = log4c_category_get("mycategory") 从配置文件中获取namemycategory 的category
  3. log4c_category_set_priority(mycat,LOG4C_PRIORITY_DEBUG); 设置日志等级
  4. log4c_category_log(mycat,LOG4C_PRIORITY_INFO,"log4c_api 配置完成"); 输出日志
  5. log4c_category_set_appender(mycat,appender); 设置 appender
    设置日志等级和输出日志部分都需要日志等级,可以使用下面的进行替换
// priority —— 输出等级,值越小的等级越高
 typedef enum {
    /** fatal */	LOG4C_PRIORITY_FATAL	= 000, 
    /** alert */	LOG4C_PRIORITY_ALERT	= 100, 
    /** crit */	      	LOG4C_PRIORITY_CRIT	= 200, 
    /** error */	LOG4C_PRIORITY_ERROR	= 300, 
    /** warn */	      	LOG4C_PRIORITY_WARN	= 400, 
    /** notice */	LOG4C_PRIORITY_NOTICE	= 500, 
    /** info */	      	LOG4C_PRIORITY_INFO	= 600, 
    /** debug */	LOG4C_PRIORITY_DEBUG	= 700,
    /** trace */	LOG4C_PRIORITY_TRACE	= 800,
    /** notset */	LOG4C_PRIORITY_NOTSET	= 900,
    /** unknown */	LOG4C_PRIORITY_UNKNOWN	= 1000
} log4c_priority_level_t;

网上的教程很少,AI的回答中使用的函数也都是log4c中没有的,我只能为后来者尽一些绵薄之力,文章讲解不清的地方请见谅,如果要想更精细的控制轮转需要把头埋进源码,希望对各位有帮助

参考

log4c 使用心得+总结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/924775.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Llmcad: Fast and scalable on-device large language model inference

题目&#xff1a;Llmcad: Fast and scalable on-device large language model inference 发表于2023.09 链接&#xff1a;https://arxiv.org/pdf/2309.04255 声称是第一篇speculative decoding边缘设备的论文&#xff08;不一定是绝对的第一篇&#xff09;&#xff0c;不开源…

Leetcode 每日一题 36.有效的数独

目录 问题描述 输入输出格式 算法思路 过题图片 代码实现 题目链接 复杂度分析 问题描述 给定一个 9x9 的数独棋盘&#xff0c;我们需要判断棋盘上已填入的数字是否有效。根据数独的规则&#xff0c;有效性需要满足以下条件&#xff1a; 数字 1-9 在每一行只能出现一次…

深入浅出UART驱动开发与调试:从基础调试到虚拟驱动实现

往期内容 本专栏往期内容&#xff1a;Uart子系统 UART串口硬件介绍深入理解TTY体系&#xff1a;设备节点与驱动程序框架详解Linux串口应用编程&#xff1a;从UART到GPS模块及字符设备驱动 解UART 子系统&#xff1a;Linux Kernel 4.9.88 中的核心结构体与设计详解IMX 平台UART驱…

韦东山stm32hal库--定时器喂狗模型按键消抖原理+实操详细步骤

一.定时器按键消抖的原理: 按键消抖的原因: 当我们按下按键的后, 端口从高电平变成低电平, 理想的情况是, 按下, 只发生一次中断, 中断程序只记录一个数据. 但是我们使用的是金属弹片, 实际的情况就是如上图所示, 可能会发生多次中断,难道我们要记录3/4次数据吗? 答:按键按下…

Web前端学习_CSS盒子模型

content padding border margin <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>CSS盒子模型</title><style></style> </head> <body> <div class"demo&quo…

将自定义 AWS S3 快照存储库连接到 Elastic Cloud

作者&#xff1a;来自 Elastic Annie Hansen, Stef Nestor 在本博客中&#xff0c;我们将介绍如何通过 Elasticsearch 的快照将我们已提交的集群数据备份到 AWS S3 存储桶中。在 Elastic Cloud&#xff08;企业版&#xff09;中&#xff0c;Elastic 在其 found-snapshots 存储…

部署 Prometheus

实验环境 IP地址服务192.168.88.10Prometheus服务端, Consul, Grafana, Node-Exporter192.168.88.77MySQL, Node-Exporter192.168.88.30Nginx&#xff0c;Node-Exporter 一、Prometheus Server 端安装和相关配置 【Prometheus1.sh】 &#xff08;1&#xff09;上传 prometh…

第29天 MCU入门

目录 MCU介绍 MCU的组成与作用 电子产品项目开发流程 硬件开发流程 常用元器件初步了解 硬件原理图与PCB板 常见电源符号和名称 电阻 电阻的分类 贴片电阻的封装说明&#xff1a; 色环电阻的计算 贴片电阻阻值计算 上拉电阻与下拉电阻 电容 电容的读数 二极管 LED 灯电路 钳位作…

汽车免拆诊断案例 | 2017款捷豹F-PACE车发动机偶尔怠速不稳

故障现象  一辆2017款捷豹F-PACE车&#xff0c;搭载2.0 L GTDi发动机&#xff0c;累计行驶里程约为16万km。车主反映&#xff0c;车辆组合仪表上发动机故障灯点亮&#xff08;图1&#xff09;&#xff0c;且发动机偶尔怠速不稳。 图1 发动机故障灯点亮 故障诊断 接车后试车…

Cobalt Strike 4.8 用户指南-第十一节 C2扩展

11.1、概述 Beacon 的 HTTP 指标由 Malleable Command and Control &#xff08;Malleable C2&#xff09; 配置文件控制。Malleable C2 配置文件是一个简单的程序&#xff0c;它指定如何转换数据并将其存储在事务中。转换和存储数据的同一程序&#xff08;向后解释&#xff0…

上传镜像docker hub登不上和docker desktop的etx4.vhdx占用空间很大等解决办法

平时使用docker一般都在Linux服务器上&#xff0c;但这次需要将镜像上传到docker hub上&#xff0c;但是服务器上一直无法登录本人的账号&#xff0c;&#xff08;这里的问题应该docker 网络配置中没有开代理的问题&#xff0c;因服务器上有其他用户使用&#xff0c;不可能直接…

[BUUCTF]ciscn_2019_n_8

题目 解题 先连接看看有什么信息 返回whats your name 没有其他信息 看程序基本信息 32位 拉到ida32查看 打开发现如下 由上述代码可知&#xff0c;需要将数组0-12装满&#xff0c;装什么都可以&#xff0c;将var[13]17才能执行system("/bin/sh") payload fro…

orangepi _全志H616

1. 全志H616简介 1.1. 为什么学&#xff1a; 学习目标依然是Linux系统&#xff0c;平台是ARM架构 蜂巢快递柜&#xff0c;配送机器人&#xff0c;这些应用场景用C51,STM32单片机无法实现 &#xff08;UI界面&#xff0c;提高用户的体验感&#xff09;第三方介入库的局限性&a…

信息收集之网站架构类型和目录扫描(一)

目录 前言 1.查看域名的基本信息 2.常见的网站架构类型 3.目录扫描 前言 最近也是到了期末周了,比较空闲,把信息收集的一些方式和思路简单总结一下,顺便学习一些新的工具和一些未接触到的知识面. 1.查看域名的基本信息 新学了一个工具,kali中的whois也可以进行查看,当然在…

消息中间件用途介绍

1. 解耦&#xff08;Decoupling&#xff09;&#xff1a; • 消息中间件能够将消息的生产者&#xff08;Producer&#xff09;和消费者&#xff08;Consumer&#xff09;分离开来&#xff0c;使它们不必直接相互依赖。这种设计降低了系统的耦合度&#xff0c;提升了系统的可扩展…

【Maven】Nexus私服

6. Maven的私服 6.1 什么是私服 Maven 私服是一种特殊的远程仓库&#xff0c;它是架设在局域网内的仓库服务&#xff0c;用来代理位于外部的远程仓库&#xff08;中央仓库、其他远程公共仓库&#xff09;。一些无法从外部仓库下载到的构件&#xff0c;如项目组其他人员开发的…

学习ASP.NET Core的身份认证(基于Cookie的身份认证3)

用户通过验证后调用HttpContext.SignInAsync函数将用户的身份信息保存在认证Cookie中,以便后续的请求可以验证用户的身份,该函数原型如下所示&#xff0c;其中properties参数的主要属性已在前篇文章中学习&#xff0c;本文学习scheme和principal的意义及用法。 public static …

【mac】终端左边太长处理,自定义显示名称(terminal路径显示特别长)

1、打开终端 2、步骤 &#xff08;1&#xff09;修改~/.zshrc文件 nano ~/.zshrc&#xff08;2&#xff09;添加或修改PS1&#xff0c;我是自定义了名字为“macminiPro” export PS1"macminiPro$ "&#xff08;3&#xff09;使用 nano: Ctrl o &#xff08;字母…

uniapp关闭sourceMap的生成,提高编译、生产打包速度

警告信息&#xff1a;[警告⚠] packageF\components\mpvue-echarts\echarts.min.js 文件体积超过 500KB&#xff0c;已跳过压缩以及 ES6 转 ES5 的处理&#xff0c;手机端使用过大的js库影响性能。 遇到问题&#xff1a;由于微信小程序引入了mpvue-echarts\echarts.min.js&…

PyTorch 模型转换为 ONNX 格式

PyTorch 模型转换为 ONNX 格式 在深度学习领域&#xff0c;模型的可移植性和可解释性是非常重要的。本文将介绍如何使用 PyTorch 训练一个简单的卷积神经网络&#xff08;CNN&#xff09;来分类 MNIST 数据集&#xff0c;并将训练好的模型转换为 ONNX 格式。我们还将讨论 PTH …