debian12 - rsyslog的安装/配置/使用

news2024/9/23 19:20:45

文章目录

    • debian12 - rsyslog的安装/配置/使用
    • 概述
    • 笔记
    • 实现
    • main.cpp
    • my_syslog.h
    • my_syslog.cpp
    • Makefile
    • Makefile的准备工作
    • END

debian12 - rsyslog的安装/配置/使用

概述

以前在debian7.5中用syslog可以。
现在准备在debian12虚拟机中做个rsyslog的实验,看syslog还能用不?
试了一下,可以的。

笔记

官方文档 - https://www.rsyslog.com/doc/installation/index.html
官方文档对新手没大用。

## 安装
sudo apt-get install rsyslog

## 查看服务是否在运行
systemctl status rsyslog

## 配置文件位置 /etc/rsyslog.conf
sudo cp /etc/rsyslog.conf /etc/rsyslog.conf.bk
sudo vi /etc/rsyslog.conf
## 配置文件不用改

sudo systemctl restart rsyslog

## 然后就可以看到 /var/log/syslog
sudo tail -f /var/log/syslog

实现

main.cpp

// @file main.cpp

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>

#include "my_syslog.h"

int fn_for_test(char c, int i, long l, float f);

int main()
{
    ns_syslog::open_syslog("test_syslog");
    
    // 设置控制变量中的日志条件, 实际应用中, 是从配置文件读取的控制开关
    ns_syslog::g_log_condition.b_EMERG = false;
    ns_syslog::g_log_condition.b_CRIT = true;
    ns_syslog::g_log_condition.b_ALERT = true;
    ns_syslog::g_log_condition.b_ERR = true;
    ns_syslog::g_log_condition.b_WARNING = true;
    ns_syslog::g_log_condition.b_NOTICE = true;
    ns_syslog::g_log_condition.b_INFO = true;
    ns_syslog::g_log_condition.b_DEBUG = true;

    // 根据控制变量, 设置日志的mask
    // 在实际应用中, 这里可以是动态设置, e.g. 配置文件检测线程发现配置变了, 需要变更某些级别的日志记录结果
    ns_syslog::set_log_level(
        ns_syslog::g_log_condition.b_EMERG, 
        ns_syslog::g_log_condition.b_ALERT,
        ns_syslog::g_log_condition.b_CRIT,
        ns_syslog::g_log_condition.b_ERR,
        ns_syslog::g_log_condition.b_WARNING,
        ns_syslog::g_log_condition.b_NOTICE,
        ns_syslog::g_log_condition.b_INFO,
        ns_syslog::g_log_condition.b_DEBUG);
        
    // 现在可以用日志宏打印日志了, 因为加了条件判断, 比直接进syslog中, 由syslog根据配置文件判断是否记录日志, 效率要高.
    
    MYLOG_EMERG("this is logtype EMERG, random = %d", rand() % 0xff);
    MYLOG_ALERT("this is logtype ALERT, random = %d", rand() % 0xff);
    MYLOG_CRIT("this is logtype CRIT, random = %d", rand() % 0xff);
    MYLOG_ERR("this is logtype ERR, random = %d", rand() % 0xff);
    
    MYLOG_WARNING("this is logtype WARNING, random = %d", rand() % 0xff);
    MYLOG_NOTICE("this is logtype NOTICE, random = %d", rand() % 0xff);
    MYLOG_INFO("this is logtype INFO, random = %d", rand() % 0xff);
    MYLOG_DEBUG("this is logtype DEBUG, random = %d", rand() % 0xff);

    // test log on function
    fn_for_test('1', 2, 3, 4.0);

    /**
    // on red hat, view syslog
    tail -f /var/log/messages | grep test_syslog

    // on debian
    tail -f /var/log/syslog | grep test_syslog
    */

    ns_syslog::close_syslog();
    
    return 0;
}

int fn_for_test(char c, int i, long l, float f)
{
    MYLOG_INFO("function input param : c = %d, i = %d, l = %d, f = %f", c, i, l, f);
    return rand();
}

/** run result
root@debian750devmin:/var/log# tail -f /var/log/syslog | grep test_syslog
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [ALERT : main.cpp.42 : main()] : this is logtype ALERT, random = 163
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [CRIT : main.cpp.43 : main()] : this is logtype CRIT, random = 151
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [ERR : main.cpp.44 : main()] : this is logtype ERR, random = 162
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [WARNING : main.cpp.46 : main()] : this is logtype WARNING, random = 85
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [NOTICE : main.cpp.47 : main()] : this is logtype NOTICE, random = 83
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [INFO : main.cpp.48 : main()] : this is logtype INFO, random = 190
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [DEBUG : main.cpp.49 : main()] : this is logtype DEBUG, random = 241
Oct 12 14:44:09 debian750devmin test_syslog[4174]: [INFO : main.cpp.69 : fn_for_test()] : function input param : c = 49, i = 2, l = 3, f = 4.000000
*/




my_syslog.h

// @file my_syslog.h
// @brief syslog日志宏的定义

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <syslog.h>
#include <unistd.h>
#include <sys/types.h>

namespace ns_syslog {

typedef struct _tag_log_condition {
    bool b_EMERG;
    bool b_ALERT;
    bool b_CRIT;
    bool b_ERR;
    
    bool b_WARNING;
    bool b_NOTICE;
    bool b_INFO;
    bool b_DEBUG;

    _tag_log_condition() {
        b_EMERG = false;
        b_ALERT = false;
        b_CRIT = false;
        b_ERR = false;

        b_WARNING = false;
        b_NOTICE = false;
        b_INFO = false;
        b_DEBUG = false;
    }
} TAG_LOG_CONDITION;

extern TAG_LOG_CONDITION g_log_condition;

// ----------------------------------------------------------------------------
// syslog macro
// ----------------------------------------------------------------------------

#define MYLOG_EMERG(fmt, ...) \
if (ns_syslog::g_log_condition.b_EMERG) { \
syslog(LOG_EMERG, "[%s : %s.%d : %s()] : " fmt, "EMERG", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_EM(fmt, ...) \
if (ns_syslog::g_log_condition.b_EMERG) { \
syslog(LOG_EMERG, "[%s : %s.%d : %s()] : " fmt, "EMERG", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_ALERT(fmt, ...) \
if (ns_syslog::g_log_condition.b_ALERT) { \
syslog(LOG_ALERT, "[%s : %s.%d : %s()] : " fmt, "ALERT", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_A(fmt, ...) \
if (ns_syslog::g_log_condition.b_ALERT) { \
syslog(LOG_ALERT, "[%s : %s.%d : %s()] : " fmt, "ALERT", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_CRIT(fmt, ...) \
if (ns_syslog::g_log_condition.b_CRIT) { \
syslog(LOG_CRIT, "[%s : %s.%d : %s()] : " fmt, "CRIT", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_C(fmt, ...) \
if (ns_syslog::g_log_condition.b_CRIT) { \
syslog(LOG_CRIT, "[%s : %s.%d : %s()] : " fmt, "CRIT", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_ERR(fmt, ...) \
if (ns_syslog::g_log_condition.b_ERR) { \
syslog(LOG_ERR, "[%s : %s.%d : %s()] : " fmt, "ERR", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_E(fmt, ...) \
if (ns_syslog::g_log_condition.b_ERR) { \
syslog(LOG_ERR, "[%s : %s.%d : %s()] : " fmt, "ERR", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_WARNING(fmt, ...) \
if (ns_syslog::g_log_condition.b_WARNING) { \
syslog(LOG_WARNING, "[%s : %s.%d : %s()] : " fmt, "WARNING", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_W(fmt, ...) \
if (ns_syslog::g_log_condition.b_WARNING) { \
syslog(LOG_WARNING, "[%s : %s.%d : %s()] : " fmt, "WARNING", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_NOTICE(fmt, ...) \
if (ns_syslog::g_log_condition.b_NOTICE) { \
syslog(LOG_NOTICE, "[%s : %s.%d : %s()] : " fmt, "NOTICE", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_N(fmt, ...) \
if (ns_syslog::g_log_condition.b_NOTICE) { \
syslog(LOG_NOTICE, "[%s : %s.%d : %s()] : " fmt, "NOTICE", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_INFO(fmt, ...) \
if (ns_syslog::g_log_condition.b_INFO) { \
syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "INFO", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_I(fmt, ...) \
if (ns_syslog::g_log_condition.b_INFO) { \
syslog(LOG_INFO, "[%s : %s.%d : %s()] : " fmt, "INFO", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

#define MYLOG_DEBUG(fmt, ...) \
if (ns_syslog::g_log_condition.b_DEBUG) { \
syslog(LOG_DEBUG, "[%s : %s.%d : %s()] : " fmt, "DEBUG", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

#define MYLOG_D(fmt, ...) \
if (ns_syslog::g_log_condition.b_DEBUG) { \
syslog(LOG_DEBUG, "[%s : %s.%d : %s()] : " fmt, "DEBUG", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \
}

// ----------------------------------------------------------------------------

void open_syslog(const char* pszLogOwner);
void set_log_level(
    bool b_EMERG = false,
    bool b_CRIT = false,
    bool b_ALERT = false,
    bool b_ERR = false,
    bool b_WARNING = false,
    bool b_NOTICE = false,
    bool b_INFO = false,
    bool b_DEBUG = false);
void close_syslog();

} // namespace ns_syslog {



my_syslog.cpp

// @file my_syslog.cpp
// @brief syslog日志宏的实现

#include "my_syslog.h"

namespace ns_syslog {

TAG_LOG_CONDITION g_log_condition;

void open_syslog(const char* pszLogOwner)
{
    openlog(((NULL != pszLogOwner) ? pszLogOwner : "my_syslog"), LOG_NOWAIT | LOG_PID, LOG_LOCAL1);
}

void set_log_level(
    bool b_EMERG,
    bool b_CRIT,
    bool b_ALERT,
    bool b_ERR,
    bool b_WARNING,
    bool b_NOTICE,
    bool b_INFO,
    bool b_DEBUG)
{
    int i_mask = 0;
    
    if (b_EMERG) {
        // LOG_EMERG 日志会阻塞控制台程序, 必须要使这个条件为false, 不能执行这里
        // LOG_EMERG 不仅是记录到日志, 还打印到正在运行的程序上, 阻塞了程序的执行. 不能用这种日志
        i_mask |= LOG_MASK(LOG_EMERG);    
    }

    if (b_ALERT) {
        i_mask |= LOG_MASK(LOG_ALERT);
    }
    
    if (b_CRIT) {
        i_mask |= LOG_MASK(LOG_CRIT);
    }

    if (b_ERR) {
        i_mask |= LOG_MASK(LOG_ERR);
    }

    if (b_WARNING) {
        i_mask |= LOG_MASK(LOG_WARNING);
    }

    if (b_NOTICE) {
        i_mask |= LOG_MASK(LOG_NOTICE);
    }

    if (b_INFO) {
        i_mask |= LOG_MASK(LOG_INFO);
    }

    if (b_DEBUG) {
        i_mask |= LOG_MASK(LOG_DEBUG);
    }

    setlogmask(i_mask);
}

void close_syslog()
{
    closelog();
}

} // namespace ns_syslog {



Makefile

# ==============================================================================
# @file Makefile
# @brief
#   lostspeed 2017-10-10
#	testcase\test_syslog\Makefile
#
# create 2 sub dir below, before make 
# lostspeed@debian12d4x64:~/src/test_syslog$ mkdir ./depend_dir
# lostspeed@debian12d4x64:~/src/test_syslog$ mkdir ./sub_dir
# ==============================================================================

MAKE_VER = ./Makefile 1.1.0.0 build 2017-10-10 18:10
BIN = test_syslog

BIN_OUT = "./"
# cat string
BIN_OUT := $(BIN)

TARGETS = ${BIN}

CC = g++

CFLAGS = -Wall \
	--std=c++98 \
	-g
	
INC_PATH = -I. \

MY_LIBS =

PRJ_LIBS = ${MY_LIBS}
LIB_LINK_OPT = -lstdc++ -pthread -lpthread -lrt -ldl

DEPEND_CODE_DIR = ./depend_dir \

DEPEND_CODE_SRC = $(shell find $(DEPEND_CODE_DIR) -name '*.cpp')
DEPEND_CODE_OBJ = $(DEPEND_CODE_SRC:.cpp=.o)

# 根目录文件不能用find来搞, 会遍历到子目录去的
ROOT_CODE_SRC = $(wildcard *.cpp)
ROOT_CODE_OBJ = $(ROOT_CODE_SRC:.cpp=.o)

SUB_CODE_DIR = ./sub_dir \
	
SUB_CODE_SRC = $(shell find $(SUB_CODE_DIR) -name '*.cpp')
SUB_CODE_OBJ = $(SUB_CODE_SRC:.cpp=.o)

help:
	@echo make help
	@echo command list:
	@echo	make rebuild

#    @echo "DEPEND_CODE_DIR = " $(DEPEND_CODE_DIR)
#    @echo "DEPEND_CODE_SRC = " $(DEPEND_CODE_SRC)
#    @echo "DEPEND_CODE_OBJ = " $(DEPEND_CODE_OBJ)

#    @echo "SUB_CODE_DIR = " $(SUB_CODE_DIR)
#    @echo "SUB_CODE_SRC = " $(SUB_CODE_SRC)
#    @echo "SUB_CODE_OBJ = " $(SUB_CODE_OBJ)

show_version:
	@echo ================================================================================
	@echo ${MAKE_VER}
	@echo ================================================================================
	ls -l -p --time-style="+%Y-%m-%d %H:%M:%S" $(find `pwd`)
	@echo --------------------------------------------------------------------------------
	
clean:
	@echo ================================================================================
	rm -f $(BIN)
	@echo ================================================================================
	rm -f $(ROOT_CODE_OBJ)
	@echo ================================================================================
	rm -f $(DEPEND_CODE_OBJ)
	@echo ================================================================================
	rm -f $(SUB_CODE_OBJ)
	@echo ================================================================================
	
all: ${TARGETS}
	@echo Makefile all...
	
	@echo **==============================================================================
	if [ -f $(BIN) ] ; \
	then \
		echo "build ok :)" ; \
	else \
		echo "build failed :(" ; \
	fi;
	@echo **==============================================================================

$(BIN): $(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ)
	${CC} ${CFLAGS} ${INC_PATH} \
	$(ROOT_CODE_OBJ) $(DEPEND_CODE_OBJ) $(SUB_CODE_OBJ) \
	${PRJ_LIBS} ${LIB_LINK_OPT} \
	-o ${BIN} \

.cpp.o:
	@echo $<
	@echo build $^ ...
	${CC} ${CFLAGS} ${INC_PATH} -c $^ -o $@

rebuild:
	@echo Makefile rebuild...
	make clean
	make all



Makefile的准备工作

先在Makefile同级目录建立2个子目录

sudo mkdir ./depend_dir/
sudo mkdir ./sub_dir

用NotePad3将Makefile的换行改成Unix风格的换行
在这里插入图片描述
然后保存Makefile, 用WindTerm传到debian12中的工程编译目录 e.g. /home/lostspeed/src/test_syslog
然后开始编译

make rebuild

确认已经开始实时查看syslog的日志文件

sudo tail -f /var/log/syslog

在实时查看syslog日志的控制台上回车几下,留出空白间隔,便于观察。

运行测试程序

./test_syslog

此时可以看到,syslog上确实收到了日志。
在这里插入图片描述

END

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年PDF转换成PPT三步走,职场小白秒变高手

这个信息满天飞的时代&#xff0c;我们几乎天天都得处理一堆文件&#xff0c;PDF和PPT这对搭档简直就是我们工作学习中的老面孔。你有没有碰到过这种头疼事&#xff1a;急着要把PDF转成PPT来准备个演讲&#xff0c;但就是找不到个又快又好使的招&#xff1f;别慌&#xff0c;今…

一文搞懂大模型!基础知识、 LLM 应用、 RAG 、 Agent 与未来发展

LLM 探秘&#xff1a;想要深入了解人工智能界的“新宠”大型语言模型&#xff08;LLM&#xff09;吗&#xff1f;本文将带你走进 LLM 的世界&#xff0c;从入门知识到实际应用&#xff0c;全方位解读这个充满魔力的“大模型”。我们将一起揭开 LLM 的神秘面纱&#xff0c;领略其…

代码随想录算法训练营第三十九天 | 198.打家劫舍 , 213.打家劫舍II , 337.打家劫舍III

目录 198.打家劫舍 思路 1.确定dp数组&#xff08;dp table&#xff09;以及下标的含义 2.确定递推公式 3.dp数组如何初始化 4.确定遍历顺序 5.举例推导dp数组 方法一&#xff1a; 动态规划-一维 方法二&#xff1a;动态规划-二维 方法三&#xff1a;动态规划-两个变…

零知识证明-基础数学(二)

零知识证明(Zero—Knowledge Proof)&#xff0c;是指一种密码学工具&#xff0c;允许互不信任的通信双方之间证明某个命题的有效性&#xff0c;同时不泄露任何额外信息 导数、偏导数 ,互质数&#xff0c;费马小定理&#xff0c;欧拉定理 1 导数 导数是微积分学中的重要概念&am…

从《黑神话:悟空》看中国3A游戏之路:历史回顾与未来展望

近年来&#xff0c;随着中国游戏行业的不断发展&#xff0c;一款名为《黑神话&#xff1a;悟空》的游戏引发了全球的广泛关注。这款游戏不仅在视觉效果和动作设计上令人惊艳&#xff0c;还被誉为中国3A游戏的里程碑。然而&#xff0c;从《黑神话&#xff1a;悟空》的发布&#…

STM32-PWM驱动呼吸灯——HAL库

&#xff08;根据B站up主keysking的STM32教程视频的笔记&#xff09; 【STM32】动画讲解轻松学会STM32的PWM_哔哩哔哩_bilibili 什么是PWM&#xff1f; PWM&#xff0c;全称为脉冲宽度调制&#xff08;Pulse Width Modulation&#xff09;&#xff0c;是一种调制技术&#xf…

对各项数据的统计汇总,集中展示,便于查看厂区情况的智慧物流开源了。

智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。构建基于Ai技术的…

【云原生】Kubernetes中常见的Pod故障排查定位与解决方案

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

3D环绕音效增强软件 Boom3D for Mac v2.0.2 中文破解版下载

Boom3D for Mac 专业的3D环绕音效增强软件中文版&#xff0c;Boom 3D是适用于Mac和Windows系统的专业音效增强软件&#xff0c;旨在通过播放器&#xff0c;媒体或流媒体服务等介质&#xff0c;在不同类型的耳机上以3D环绕效果播放媒体内容。您无需使用昂贵的耳机或其他附加环绕…

第十四章- 面对墙壁

这是最后的例子&#xff1a;一个完整的游戏。 我们添加键盘快捷键并引入鼠标事件到CannonField。我们在CannonField周围放一个框架并添加一个障碍物&#xff08;墙&#xff09;使这个游戏更富有挑战性。 lcdrange.h包含LCDRange类定义lcdrange.cpp包含LCDRange类实现cannon.h…

Linux 必备:“lsof” 命令 —— 解开系统资源的神秘密码

lsof 似侦探&#xff0c;揭示 Linux 中文件进程关系。图文指南助您探索。 lsof应急排查的作用 发现非法连接&#xff0c;检测未经授权的访问或攻击。定位服务故障&#xff0c;查看是否有进程占用关键端口。找出资源占用过高的进程&#xff0c;优化系统性能。追踪恶意软件的异…

博主正在AI+宠物创业中...

最近开始创业啦&#xff0c;csdn上没太大时间一一回复大家&#xff0c;说一声抱歉啦&#xff01; AI宠物创业中&#xff0c;宠有灵犀CTO&#xff0c;北大硕士 双学位 前阿里巴巴达摩院&#xff0c;邮箱17387842007163.com 我们瞄准了宠物赛道&#xff0c;做的是 供应链电商社交…

One-for-All:上交大提出视觉推理的符号化与逻辑推理分离的新范式 | ECCV 2024

通过对多样化基准的严格评估&#xff0c;论文展示了现有特定方法在实现跨领域推理以及其偏向于数据偏差拟合方面的缺陷。从两阶段的视角重新审视视觉推理&#xff1a;&#xff08;1&#xff09;符号化和&#xff08;2&#xff09;基于符号或其表示的逻辑推理&#xff0c;发现推…

罐装食品检测检测系统源码分享 # [一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

罐装食品检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

一起学习LeetCode热题100道(57/100)

57.电话号码的字母组合(学习) 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digit…

ETL数据集成丨实现SQLServer数据库的高效实时数据同步

SQL Server&#xff0c;作为一款功能强大的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;在企业级应用中占据着举足轻重的地位。它不仅提供了可靠的数据存储与管理能力&#xff0c;还集成了高级数据分析、报表服务、集成服务以及商业智能等功能&#xff0c;为…

如何使用 500 多个表构建企业级 AI 查询向导

迄今为止的旅程&#xff1a;Confluence Agent 回顾 在深入研究 SQL Agent 之前&#xff0c;让我们先简单回顾一下我们开发的 Confluence Agent&#xff1a; 元数据提取&#xff1a;捕获我们的知识库的结构。内容提取&#xff1a;提取文档的核心内容。格式处理&#xff1a;分离 …

台灯应该买什么样的才能护眼?适合孩子的护眼台灯挑选指南

2022年3月1日起&#xff0c;正式实施的《儿童青少年学习用品近视防控卫生要求》&#xff08;GB 40070-2021&#xff09;规定了与近视防控相关的读写作业台灯卫生要求。台灯应该买什么样的才能护眼&#xff1f;要求从照度、均匀度、显色指数、色温、防蓝光等方面去完善护眼台灯&…

如何利用 Go 语言开发高可用服务

高可用的含义是尽量减少服务的不可用&#xff08;日常维护或者突发系统故障&#xff09;时长&#xff0c;提升服务的可用时长。如何衡量一个服务的可用性呢&#xff1f;或许你也听说过&#xff0c;通常企业可能会要求服务的可用性能能够达到三个 9(也就是 99.9%)或者 4个 9 &am…

手机三要素验证API接口,选择的时候应该注意什么?

在选择手机三要素验证API接口时&#xff0c;为了确保接口的安全性、可靠性和适用性&#xff0c;需要注意以下几个方面&#xff1a; 服务商的合法性和资质 合法性&#xff1a;确保服务商具有合法的经营资质和业务范围&#xff0c;以避免法律风险。 资质认证&#xff1a;查看服务…