Nest框架: 日志功能之收集,筛选,存储,维护

nestjs日志存储到logs文件夹 项目上线后,日志如果还依赖console的方式显示在控制台的话,无法方便查看。需要将日志存储到/logs文件夹中,根据访问时间进行查询 阅读详情

日志功能扩展:优化日志收集与筛选

  • 在项目打包上线之后,我们不可避免地需要了解服务器的运行状态以及服务器上的一些错误日志等信息

  • 这些错误日志等信息本身存放在服务器里,以文件形式存放

  • 在 src/common/logger 里面有一个叫 logs.module.ts,

    import { Module } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { WinstonModule } from 'nest-winston';
    import {
      consoleTransports,
      createRotateTransport,
    } from './createRotateTransport';
    
    @Module({
      imports: [
        WinstonModule.forRootAsync({
          inject: [ConfigService],
          useFactory: (configService: ConfigService) => {
            const logOn = configService.get('LOG_ON') === 'true';
            return {
              transports: [
                consoleTransports,
                ...(logOn
                  ? [
                      createRotateTransport('info', 'application'),
                      createRotateTransport('warn', 'error'),
                    ]
                  : []),
              ],
            };
          },
        }),
      ],
    })
    export class LogsModule {}
    
  • 在这个模块里我们使用到了一个模块,叫 WisdomModule, Wisdom 是一个日志模块,当我们开启本地的日志标签后 LOG_ON,它会把这些日志以文件形式存放到本地目录中。

  • 具体会存放到 logs 目录下, 可参考 createRotateTransport.ts 的文件里,并且按照日期的形式进行滚动存储

    import DailyRotateFile from 'winston-daily-rotate-file';
    import { format } from 'winston';
    import { Console } from 'winston/lib/winston/transports';
    import { utilities } from 'nest-winston';
    
    export const consoleTransports = new Console({
      level: 'info',
      format: format.combine(
        format.timestamp(),
        format.ms(),
        utilities.format.nestLike('Winston'),
      ),
    });
    
    export function createRotateTransport(level: string, fileName: string) {
      return new DailyRotateFile({
        level,
        dirname: 'logs',
        filename: `${fileName}-%DATE%.log`,
        datePattern: 'YYYY-MM-DD-HH',
        zippedArchive: true,
        maxSize: '20m',
        maxFiles: '14d',
        format: format.combine(format.timestamp(), format.simple()),
      });
    }
    
  • 这里可能会有几个问题:

      1. 占用系统 IO:写磁盘会占用系统的 IO。
      1. 数据处理不便:这些数据不方便进行下载、浏览和筛选。
      1. 占用系统空间:数据量大了之后,会占用系统空间,需要定期进行清理
      1. 日志分散难汇总:
      • 后续当服务端项目变得复杂,日志可能会变得分散,不方便浏览汇总
      • 例如,服务端项目或某个服务进行多节点部署并做负载均衡时,既有服务端的日志,也可能有 nginx 上面的访问日志
      • 在出现节点问题或功能性问题时,需要快速汇集这些日志进行查看、筛选和排错定位问题
      • 线上系统运行时,要快速修复功能并回稳,还需通过日志收集来论证系统功能是否修复,这就需要快速响应并方便地汇总这些日志
  • 到最后,这其实涉及到分布式的日志系统

    • 分布式的日志系统有很多,如 ELK Stack、Graylog、Fluentd、Prometheus
    • 还有大家熟知的错误收集系统 Sentry 等,这些都是用于日志收集或系统监控的工具
    • 我们把这个层级的扩展放到后面,现在重点看看前面这些问题如何优化
  • 问题及优化方案分析

      1. 占用系统磁盘 IO:
      • 无论哪种日志系统,要么往本地磁盘写,要么往数据库或其他服务器的文件写,都会占用磁盘 IO 或网络带宽。
      • 对于单服务器、单 NestJS 的简单业务系统,如简单的小程序,使用文档类型的日志系统没问题,Wisdom 就提供了类似方案,它支持通过 HTTP Transport 的方式将日志文件发送到远端的静态资源服务器,还支持一些简单的权限验证
      • 但这种方式会占用一定的系统网络带宽,且发送日志频率不能太高,同时也无法解决多服务日志的筛选汇总问题
      1. 日志筛选汇总难题
      • 为了解决这个问题,我们介绍 MongoDB Transport 方式,即往本地或其他网络互通且网络情况较好的数据库服务器写日志数据
      • 选择往其他机器的数据库写日志,一是因为本地局域网网络没有带宽限制,网速有保障;二是不会占用业务系统本身的系统 IO;此外,数据库兼顾了筛选和存储功能,可以存储多个服务的日志
  • 接下来,我们按照 MongoDB Transport 部分进行实操,看看常见的选项以及如何配置,同时修改原先的项目,为用户提供更多选择,比如将 Wisdom Transport 配置到对应的数据库上,以解决日志数据集中和筛选的问题

Winston - MongoDB 日志数据库存储方案:配置、测试与优化全解析

  • 看一下这个 winston - MongoDB 是如何进行配置的 winston-mongodb
  • 使用的是 winston 3.x 版本,对应需要集成的是 2.0.6 版本的 winston-mongodb

1 ) 配置动机与应用

这边我们先介绍一下它的动机(motivation),主要是为了扩展 winston 的日志功能,让其实现解耦,使 winston 专注于日志记录,而 winston 的插件则用于实现其他扩展功能

  • 下面是一个具体应用示例

    const winston = require('winston');
    // Requiring `winston-mongodb` will expose winston.transports.MongoDB`
    require('winston-mongodb');
    
    const log = winston.createLogger({
      level: 'info',
      transports: [
        // write errors to console too
        new winston.transports.Console({format: winston.format.simple(), level:'error'})
      ],
    });
    
    // logging to console so far
    log.info('Connecting to database...');
    
    const MongoClient = require('mongodb').MongoClient;
    const url = "mongodb://localhost:27017/mydb";
    
    const client = new MongoClient(url);
    await client.connect();
    
    const transportOptions = {
      db: await Promise.resolve(client),
      collection: 'log'
    };
    
    log.add(new winston.transports.MongoDB(transportOptions));
    
    // following entry should appear in log collection and will contain
    // metadata JSON-property containing url field
    log.info('Connected to database.',{url});
    
  • 这里 创建了一个 transport

    • new winston.transports.Console({format: winston.format.simple(), level:'error'})
    • 在这个 transport 中,不仅可以在控制台(console)打印日志
  • 还创建了另一个 transport

    • log.add(new winston.transports.MongoDB(transportOptions));
    • 调用了其中名为 MongoDB 的方法,并引用了上面的 transportOptions
    • 这个 options 包含一个 MongoDB 客户端,支持众多选项,如下
  • db:这是一个 MongoDB 的连接字符串,包含数据库名称、连接的用户名和密码等信息。不过,这些设置并非都必须配置。

  • 其他 MongoDB 配置选项:如连接池、是否连接、是否使用新的 URL 转换工具(newUrlParser)等,默认设置通常即可。若用户有定制需求,可在模块中传递相应参数。

2 ) 依赖安装

  • 回到项目, 打开终端工具,使用 pnpm i winston-mongodb 安装依赖包,我的版本是 5.1.1
  1. 模块配置
  • 安装完成后,我们开始配置对应的模块。之前我们在某个地方添加了一个 LOG_ON 标志,写在 env 配置文件中

  • 同样,我们也可以将与日志和 MongoDB 相关的配置写在这里。常见选项如下:

    #是否开启日志
    LOG_ON=true
    # file & mongo
    LOG_TYPE=mongo
    LOG_DB=mongodb: //root: example@localhost:27017/nest-logs
    LOG_STOREHOST=false
    LOG_COLLECTION=log
    LOG_LEVEL=error
    LOG_CAPPED=true
    LOG_CAPPED_SIZE=10000000
    LOG_CAPPED_MAX=1000
    
  • LOG_CAPPED_SIZE:用于设置滚动连接(connections)的大小,默认值是一千万字节(bytes),约为九点几兆。

  • LOG_TYPE:默认有两种类型,file 和 mongo,我们将其设为 mongo 以作区分。

  • LOG_DB:这是 MongoDB 的连接地址,我们复制之前使用过的 MongoDB 地址,例如将数据库名改为 messagesLogs,这里的用户和数据库都需要重新创建。

  • 其他选项

    • 如 LOG_COLLECTION(默认连接是否为 log)
    • LOG_LEVEL(默认是 info)
    • LOG_CAPPED(默认是 false,可设为 true)
    • LOG_CAPPED_MAX(最大连接数量,无默认值,可自行设置)
    • LOG_STOREHOST(将机器的主机名存入 MongoDB 中,默认是 false,可调整位置)日志数据会多出来一条 hostname 的属性

配置完成这些选项后,我们就可以在 logs.modules.ts 中使用了

4 ) 创建 Transport 方法

  • 在 createRotateTransport.ts 中创建一个 createMongoTransport 方法:
import { MongoDB, MongoDBConnectionOptions } from 'winston-mongodb';

export function createMongoTransport(options: MongoDBConnectionOptions){
	return new MongoDB(options);
}
  • 同时,我们需要从配置文件中读取默认属性项并传递给它, 下面改造 log.module.ts

5 ) 定制 log.module.ts

  • 在 logModules 中,我们根据 lockType 的值选择不同的 transport:
@Module({
  imports: [
    WinstonModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => {
        const logOn = configService.get('LOG_ON') === 'true';
		const logType = configService.get('LOG_TYPE'); 
		let transportArr = [];
		if (logOn) {
			if (logType === 'mongo') {
			    const defaultOptions = {
			        // 从配置文件中读取的一系列与 MongoTransport 相关的配置 
					db: configService.get('LOG_DB'),
					collection: configService.get('LOG_COLLECTION'),
					level: configService.get('LOG_LEVEL'),
					capped: configService.get('LOG_CAPPED')=='true',
					cappedSize: parseInt(configService.get('LOG_CAPPED_SIZE', '10000000'), 10),
					cappedMax: parseInt(configService.get('LOG_CAPPED_MAX', '10000'), 10),
					storeHost: configService.get('LOG_STOREHOST')=='true',
					options: { 
						useUnifiedTopology: true,
						poolSize: 2,
						// autoReconnect: true, // 与 上面 useUnifiedTopology 不兼容
						useNewUrlParser: true,
					},
			    };
			    transportArr = [createMongoTransport(defaultOptions)];
			} else if (logType === 'file') {
			    // 处理 file 类型的 transport
			    transportArr = [
	                  createRotateTransport('info', 'application'),
	                  createRotateTransport('warn', 'error'),
	                ]
			}
		}
		transportArr.push(consoleTransports);

        return {
          transports: transportArr
        };
      },
    }),
  ],
})

6 ) 测试与问题解决

  • 创建数据库和用户:创建一个 NestJS 的 MongoDB 数据库,并创建一个 MongoDB 用户,设置其权限。可以使用命令行,如 docker exec -it <容器名> mongo -u root -p 连接数据库

    • docker exec -it nestjs-starter-mongo-1 mongo -u root -p
    • use nest-logs
    • 创建用户
      db.createUser({
      	user:"root",
      	pwd:"example",
      	roles: [
      		{
      			role:"dbOwner",
      			db:"nest-logs"
      		}
      	]
      });
      
    • 输出
      Successfully added user: {
      	"user":"root",
      	"roles": [
      		{
      			"role": "dbOwner",
      			"db":"nest-logs"
      		}
      	]
      }
      
  • 测试配置:启动进程后可能会遇到各种问题,如认证失败、日志无数据等。我们需要逐步排查,例如检查密码拼写、添加或调整 MongoDB 客户端的额外选项(如 autoReconnect 等)、确保 logOn 在环境配置文件中设置为 true 等。

  • 生成日志数据:在登录或注册模块中使用 logger 记录日志,发起请求并检查 log 中是否有数据。若没有数据,可继续调整配置,直到日志正常记录到 MongoDB 中。

7 ) 日志筛选与优化

  • 我们可以通过设置 level 属性来筛选日志,例如将 level 设为 error,这样只有错误级别的日志会被记录
  • 同时,设置 storeHost 为 true 后,每条日志会多一个 hostname 属性,方便在服务器端区分不同服务器产生的错误
  • 通过以上步骤,我们完成了 MongoDB 配合 winston 进行日志收集的功能,这种配置方式解决了磁盘 IO 占用、数据库下载筛选不便以及日志配置分散等问题

数据库日志存储与维护机制:问题、解决方案及实践探索


1 ) Wisdom与Mongo集成存在的问题

  • 之前一节我们完成了Wisdom与Mongo级别的集成
  • 但细想之下,仍存在一些不便之处:
      1. 日志设置局限性:存储的日志只能通过日志级别进行设置。
      1. 错误日志筛选不便:
      • 对于错误日志,难以快速筛选,需要了解MongoDB的查询语句
      • 在数据库操作界面进行查询时,即便能通过如level等条件查询,但时间节点可能不一致,还需补充查询条件

2 ) MongoDB数据库日志存储问题及应对

  • 日志数据存储压力
    • MongoDB数据库中若存放大量英文数据,可能会很快写爆日志服务器
    • 因此,对于日志服务器及其存储,需要加入清理操作
  • 定时清理任务
    • 清理操作并非每天执行,需考虑定时任务
    • capped、cappedSize、cappedMax选项的作用是滚动日志的属性项
      • 若将capped设置位 true 后,会尝试创建新的 log
      • cappedSize 会记录所有日志的大小
      • cappedMax 是设置日志大小

3 )日志存储测试与分析

  • 测试过程

    • 将capped设置为 10,cappedSize设置为一千,LOG_LEVEL设置为info,删除数据库连接,重启项目,发现日志只有一条数据
    • 原因是在cappedMax配置中设置了日志大小,达到上限便不再产生数据
    • 增大该值后再次测试,删除logconnection,重启调试进程,发现日志数据不会超过十条,保存操作会使数据滚动
  • 属性设置建议:建议保持这三个属性的默认值,即capped设为false,不创建新的connection;cappedSize约为9.3兆的日志空间;cappedMax不设置,可无限记录文件数量。查看源码可知,未设置时这三个值为空

4 ) 合理的日志存储方案

  • 不同业务场景的选择
    • 根据业务场景选择存储方案, 小型业务系统可使用文档或数据库存储
    • 文档方案检索不便,数据库方案便于多台机器部署的服务端应用进行日志汇总、筛选和查询,集中式数据库存储方案较为理想
  • 其他存储方案及扩展操作
    • Wisdom还提供了如HTTP的方案,但仍离不开文档方式
    • 使用数据库后,可创建简单界面进行数据查询和筛选
    • 更进一步,需对MongoDB数据库进行滚动或备份操作,可编写服务器定时维护脚本,按时间(如月、三个月、七天等)滚动备份日志数据,此思路与配置Wisdom的DailyRotateFile类似
第二十三章 Nest集成日志框架Winston Winston是一个非常流行的Node.js日志框架,而Nest.js是一个基于Node.js的后端框架。修改 winston.module.ts 内容如下 添加 forRoot 方法,接收 winston 的 createLogger 方法的参数,返回动态模块的 providers、exports。这里用到了 printf 的 format 函数,它可以自定义打印的日志格式 且使用了chalk 加上了颜色,并且打印了 dayjs 格式化的时间。可以看到控制台打印了自定义的 logger 的自定义。 阅读详情

相关推荐

【信息科学与工程学】【数据中心】 第三篇 智算中心全业务场景矩阵

技术:MPI/OpenMP优化、InfiniBand/RoCE网络、Lustre/GPFS并行文件系统。技术:NVLink/NVSwitch高速互联、RDMA网络、检查点存储、混合精度训练。技术:Kubernetes运营商、服务网格、Serverless框架。技术:VXLAN/EVPN、SRv6、智能网卡、DPDK/智能网卡。运营:AI框架优化、显存优化、容错训练、多租户GPU隔离。技术:KVM/ESXi虚拟化、SR-IOV、智能网卡、快速发放。

weixin_49199313的博客 1074

彩虹表攻击与Nest密码存储

彩虹表攻击(Rainbow Table Attack)彩虹表攻击是一种基于预计算哈希值反查密码攻击者先构建一个表格:记录常见密码及其哈希值(如 MD5/SHA1);获取某网站数据库中的用户密码哈希值;在彩虹表中查找匹配的哈希值,反推出原始密码。做法是否推荐说明明文存密码❌ 绝对禁止泄露即全部破防MD5/SHA1❌ 不推荐无加盐太容易被破解哈希 + Salt✅ 推荐每个用户不同结果,防彩虹表✅ 推荐更安全的现代密码哈希方法。

Bruce__taotao的博客 1307

三级等保网络拓扑图实战:从零搭建符合标准的医院安全架构

本文详细阐述了如何从零开始设计并搭建符合三级等保标准的医院网络安全架构。文章基于“一个中心,三重防护”的核心框架,深入解析了医院网络分区设计、安全域划分、关键安全设备选型与配置等实战要点,并提供了绘制专业网络拓扑图的技巧与等保测评准备指南,旨在帮助医院IT人员系统化地构建既合规又实用的纵深防御体系。

weixin_29326909的博客 505

告别日志混乱:Nest.js结构化日志与监控实战指南

你是否还在为Node.js应用中的日志管理头疼?控制台打印的零散信息难以追踪问题,生产环境排查故障如同大海捞针?本文将带你全面掌握Nest.js日志系统,从基础配置到高级监控集成,用结构化日志构建企业级可观测体系。读完你将学会: - 5分钟上手Nest.js内置日志服务 - 定制JSON结构化日志输出 - 集成Winston实现日志分级存储 - 对接Prometheus监控告警 - 实战案例:从...

gitblog_00056的博客 1206

图形引擎实战:镭射效果制作分享

该方案的优势1.遵循物理的2.可以使用少量的参数去调控镭射的效果。计算相对简单,缺点仍是颜色不能够自定义,还有一种常见的方案是采样一张镭射贴图来模拟,好处是颜色可以自定义同时性能上还很高效没有复杂的公式计算。我查阅了网上普遍的方案,常见的做法是制作一个Ramp图生成工具,然后将生成好的ramp图赋给材质。这两个方案的好处是美术同学可以手动的去控制镭射的颜色。最后就是Shader中对Ramp图的采样的部分,Ramp图的UV坐标是使用fresnel作为Ramp的U轴坐标,0.5作为V轴坐标。

qq_41166022的博客 1361

联想服务器ThinkSystemRAID阵列设置教程

关注我不迷路,全是干货! 以联想ThinkSystemSR530为例子进行示范。 开机点按【F1】 点击——【UEFI设置】 依次点击——【系统设置】——【存储】 点击——【RAID卡】 PS:本次服务器配置的是730-8i 阵列卡,按实际情况选中需要设置的阵列卡即可。 点击——【Main Menu】 点击——【Configuration Management】 点击——【Create Virtual Drive】 点击——【Select RAID Leve..

littlelotusK的博客 2万+

NestJS 存储管理器:squbeboat/nest-storage 快速入门指南

NestJS 存储管理器:squbeboat/nest-storage 快速入门指南 1. 目录结构及介绍 squereboat/nest-storage 是一个专为 NestJS 设计的多磁盘、多驱动文件系统管理工具,它提供了一致且统一的API来处理不同存储驱动和磁盘上的操作。以下是典型的项目目录结构概览: .github: 此目录包含了与GitHub工作流相关的文件,如Issue模板。 LI...

gitblog_00649的博客 822

华为2019秋招笔试Java实现(2)

华为2019秋招笔试Java实现(2) 笔试日期2019年8月14日 第二题(200分) 题目描述 某程序员小A,有一种表格数据需要存储在文件中。表格中的每一行,由若干个字段组成,每个字段可以是整数或字符串(字符串只包含数字、字母以及特殊字符!@#%^&*()",)。小A设计了一种存储格式,采用文本的方式对表格数据进行存储。文本文件中的每一行,代表了表格数据中的一行数据。具体格式描述如下: 1、采用逗号分隔不同的字段(逗号前后无空格); 2、数字直接采用10进制的文本存储; 3、字符串的存储规则如下

hewhys的博客 1550

1.3. Next.js与Nest.js在AI数据分析中的角色

本文探讨了Next.js与Nest.js在全栈AI数据分析应用中的分工协同方案。Nest.js负责后端核心业务逻辑,包括数据接入转换、模型工具集成、任务编排和持久化管理;Next.js专注于前端交互呈现,实现仪表盘、可视化图表和实时更新等功能。两者通过API/WebSocket通信,形成职责分离、可扩展的全栈架构。这种组合充分发挥了TypeScript端到端优势,支持并行开发和独立演进,为复杂AI数据分析应用提供了工程化的解决方案。

雨夜 202

SAP 货币类型和公司代码的货币设置

货币类型分为公司代码和集团货币,一般FI 10类型和集团货币 30,事务代码是8KEM; 设置货币类型的事务代码是OB22 在S/4 1809版本里编辑功能统合到事务代码FINSC_LEDGER 中了,这里集中了分类账和公司代码的设置; 设置多账簿的币种(会出现在BSEG和FAGLFLEXA表中) 汇率维护在TCURR表中,可通过BAPI_EXCHANGERATE_GETDETAIL函数获取。 CO货币的事务代码是成本控制范围货币:OKKP ,一般设置为货币码20和30; 另外, SCC4设置集团货币,

RichardYang2020的博客 1万+

S4HANA - Cost Elements成本要素

SAP这里面的配置逻辑很像,就是先建一个对象,然后不停给这个对象附加一些属性,给一个账户附加编号范围,附加账户组。所有模块的维度都在这个表里,看下图的GL,CO,COPA,AA,ML的都在ACDOCA里。要把这5个类型和六大要素对应,先得把六大要素和账户类型对应下(以下是个人理解,不知道对错):当然那个C是新来的,我觉得放在资产下面也行,就不画图了。S4的嵌入式分析是在业务逻辑都整套嵌入的情况下,预开发了数据模型,所以它能提供的就不仅是原始数据了,它能提供的是包含所有相关联的上下文的信息数据。

weixin_45689053的博客 2395

NestJS宽事件(Wide Events)详解:使用nestjs-otel构建上下文丰富的请求日志

NestJS宽事件(Wide Events)是nestjs-otel模块提供的一种强大功能,它能为每个请求创建一个上下文丰富的结构化事件,整合整个请求生命周期中的属性。通过OpenTelemetry实现的这一模式,开发者可以轻松构建全面且易于分析的请求日志系统。 ## 什么是NestJS宽事件 宽事件(也称为规范日志行)为每个请求发出一个上下文丰富的事件,其中包含在整个请求生命周期中累积的属性

gitblog_00459的博客 648

清理异常值(MAD:绝对中位差)

清理异常数据: 中位数绝对偏差(MAD):用来描述单变量样本在定量数据中可变的一种标准 在统计学中,绝对中位差是刻画一元数据样本变化的一个鲁棒度量。由公式可以看出,其求解还算简单,给定一个数据样本集,首先求其中位数,然后求原始数据减去中位数的绝对值从而形成一个新的数据样本,再求新的数据样本的中位数即为绝对中位差。比如说有一个数据样本集X={2 3 8 7 9 6 4},这时候数据的中位数是6,原...

spider_man 1万+

基于Node.js+Express的校友管理系统设计与实现指南

Node.js凭借事件驱动和非阻塞I/O模型,在后端开发中备受青睐。Express作为其最成熟的Web框架,以简洁的中间件机制和丰富的生态,成为快速构建业务系统的首选。对于高校校友管理场景,系统需要将分散的校友数据统一收拢,实现信息检索、身份认领、活动报名等核心功能。通过MySQL合理设计数据表与索引,配合Express的会话控制与权限中间件,即可构建安全可靠的管理平台。本文围绕这一工程实践,从需求拆解、技术选型、数据库设计到核心模块编码,系统讲解基于Node.js与Express的校友管理系统开发全过程,

weixin_32576389的博客 315

【图论】系列(七)图论的中心性度量方法及重要性评价指标

图论中的中心性度量方法是用来衡量图中各个节点(或顶点)相对重要性的指标。

qq_30066733的博客 1078

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

langchain AI应用框架研究【核心概念-篇一】

langchain新版本1.1.0 出来了,老板了的api看了一些,api写法看起来有些凌乱,特别是那个构造chain的地方,先后顺序感觉不好记忆,还是SpringAI相对好好记忆一些。不知到1.x版本的会好使一些不。我们先来看看新版的langchain、langgraph、deepagents。LangChain 是一个用于开发由大语言模型(LLM)驱动的应用程序的开源框架。它的核心目标是提供一个统一的抽象层,让开发者可以方便地组合各种组件,而无需关心底层与不同模型API对接的细节。

yanghuashuiyue的专栏 601

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

FastAPI构建高考信息聚合助手API:数据模型与接口实现

在数字服务与信息聚合类业务中,API接口设计是连接多源数据与用户请求的关键环节。当高考相关公告分散在不同网站、格式与更新周期中,一套统一的数据模型能显著降低整合成本并提升信息可信度。本文从数据抽象出发,介绍如何基于FastAPI搭建聚合型查询服务,将官方渠道的进度信息标准化为统一字段,封装支持筛选、排序、分页的查询接口和自然语言汇总接口。该方案适用于教育数据、政府公开信息等多源汇聚场景,既能帮助开发者快速构建BFF层,又能为用户提供可追溯的官方来源链接。文章结合高考智能助手的具体案例,覆盖种子数据准备、参数

weixin_33978044的博客 436

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Roblox 数据层专家笔记精读:用实测结论校正 DataStore、ProfileStore 与存档交易的常见认知

这篇技术精读围绕 `skills` 仓库中 Roblox 数据技能(scenario-roblox-data)的专家笔记展开,逐条梳理「来源断言 → 实测结果 → 应采用的正确做法」这一证据链。读者读完后能够掌握:2026 年 Roblox DataStore 配额与版本机制的真实边界、ProfileStore 会话锁的完整交接时序、交易与开发者产品在崩溃场景下的幂等设计,以及如何在不发布 pla

gitblog_00981的博客 761

Phoenix AI 可观测性平台实战指南:基于 OpenTelemetry 的 LLM 追踪、评估与生产监控(AI-Research-SKILLs)

Phoenix 是 Apache 2.0 协议开源、可完全自托管的 AI 可观测性平台,为 LLM 应用提供 OpenTelemetry 追踪、LLM-as-judge 评估、版本化数据集、实验对比与实时监控能力。本文以 AI-Research-SKILLs 仓库中 [phoenix 技能文档](https://link.gitcode.com/i/e55620077171f2581ea18e57

gitblog_00392的博客 871

开源TMS选型与落地指南:7大项目横评与二次开发实战

运输管理系统(TMS)是物流数字化的核心,它通过信息化手段管理运单、调度、跟踪与结算,旨在解决传统物流中信息孤岛、效率低下与成本高昂的痛点。其技术原理在于整合订单、车辆、位置与费用数据流,构建协同工作流。对于成长型企业而言,TMS的价值在于实现流程标准化、运营可视化与决策数据化,从而降本增效。应用场景广泛覆盖电商配送、零担货运、国际货代及供应链协同。本文聚焦于开源TMS这一低成本、高自主性的解决方案,针对微服务架构、API优先设计等热门技术趋势,深度横评了OpenTMS、FreightTMS等7个项目的技术

weixin_30800987的博客 358

在 Windows 上直接安装 Android 应用:APK Installer 使用指南

想在 Windows 电脑上装一款 Android 应用,又不想折腾模拟器。APK Installer 可以办到这件事,它是一个免费开源的 Windows 工具,专门用于在 Windows 上直接安装 Android 应用。流程是:把 APK 拖进窗口,确认应用信息,点击安装,应用就能出现在开始菜单里。以下内容根据项目的 README 和源码整理。 ## 能不能直接装:三个硬性前提 按官方文档

gitblog_00591的博客 768

包管理工具(npm、pnpm、yarn、cnpm)、版本管理工具(nvm、fnm)

包管理工具(npm、pnpm、yarn、cnpm)、版本管理工具(nvm、fnm)

freeking101的博客 4万+

如何构建一个完全自主掌控的智能照片管理平台?

在数字时代,我们每天都会产生大量的照片和视频,但面对海量的数字记忆,传统的云存储服务不仅费用高昂,更存在隐私泄露的风险。当您将珍贵的家庭照片、工作资料和个人回忆托付给第三方平台时,是否曾想过这些数据的安全边界在哪里?**Immich** 作为一个高性能的自托管照片和视频管理解决方案,为技术爱好者和开发者提供了一个全新的选择——将数据控制权完全交还给用户。 ## 数据主权危机:为什么我们需要自托管

gitblog_00314的博客 512

OpenClaw技能库解析:GitHub热门AI助手生态与自动化实践

模块化AI技能库是现代自动化工作流的核心技术,通过分布式架构实现功能扩展。OpenClaw作为开源AI助手框架,采用类似Homebrew的生态管理机制,支持5300+社区贡献技能,涵盖GitHub操作、智能家居控制等场景。其技术价值在于三层安全防护体系(注册预筛、病毒扫描、运行隔离)和灵活部署方案(CLI直装、工作区隔离、聊天交互)。典型应用包括开发者效率套件(自动PR合并、多代理协同编码)和智能自动化工作流(RPA优化、验证码破解)。该生态通过ClawHub官方注册中心和社区精选列表实现质量管控,已过滤7

433

TREK 插件管理与安全治理实战:生产实例上零源码改动的插件运维

TREK 插件系统允许在不改动宿主一行源码的前提下,为自托管实例接入仪表盘 widget、独立页面、行程页标签,以及照片、日历、通知渠道等集成。Admin → Plugins 管理面板是插件管理面板的核心入口,覆盖安装、审查、授权、更新到卸载的完整安全生命周期。本文不按操作步骤流水账,而是以信任模型为主线:先讲清系统能担保什么、不能担保什么,再讲每个机制为什么这样设计,读完你可以在生产实例上安全、

gitblog_01052的博客 326

基于Hermes Agent的AI技术社区自动化运营架构与实践

AI Agent作为人工智能领域的重要技术范式,其核心在于通过大语言模型赋予系统自主感知、决策与执行能力。其工作原理通常基于提示工程、工具调用与工作流编排,技术价值体现在自动化处理复杂任务、提升效率与可扩展性。在应用场景上,AI Agent广泛应用于智能客服、内容审核、自动化运维等领域。本文聚焦于AI Agent在技术社区自动化运营中的深度实践,详细阐述了如何利用Hermes Agent框架构建一个集内容审核、智能问答、氛围维护于一体的自动化运营体系,并深入探讨了在集成RAG(检索增强生成)技术、应对大模型

weixin_34392435的博客 406
上一篇: Monorepo架构: Nx Cloud 扩展能力与缓存加速
下一篇: Nestjs框架: nestjs-schedule模块注册流程,源码解析与定时备份数据库
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值