go 问题记录(日志丢失)
问题描述:
在go程序中,通过执行一个命令启动一个子命令,并通过pipe读取子程序的标准输入和输出,通过scanner默认按行读取,此时如果子程序输出时没有携带’\n’,scanner就不会打印输出,而是会累积到缓存buf上限,最终被丢弃,直到遇到一个\n,然后输出所有的内容,默认buf缓存上限时65536,如果日志打印处还有限制,如glog就限制最大的打印字节数为4096,那么就会导致日志再次丢失。
解决方法:
不适用scanner去按行读取,直接读取管道的内容,然后设置上限,超过时或者遇到’\n’时打印
测试代码:
子程序:
#include <stdio.h>
#include <unistd.h>int main() {
int count = 0;while (1) {fprintf(stderr, "%d", count);count = (count + 1) % 10;usleep(500); // Sleep for 500,000 microseconds (0.5 seconds)
}return 0;
}
主程序:
package mainimport ("bufio""fmt""os/exec""strings""log"
)func main() {cmd := exec.Command("./test")stdout, err := cmd.StdoutPipe()if err != nil {fmt.Println("Error creating StdoutPipe:", err)return}cmd.Stderr = cmd.Stdouterr = cmd.Start()if err != nil {fmt.Println("Error starting command:", err)return}scanner := bufio.NewScanner(stdout)// scanner.Split(bufio.ScanBytes)// buf := ""// for scanner.Scan() {// buf += scanner.Text()// if strings.Contains(buf, "\n") || len(buf) >= 256 {// log.Printf("%s", buf)// buf = ""// }// }for scanner.Scan() {log.Printf("%s", scanner.Text())}if err := scanner.Err(); err != nil {fmt.Println("Error reading standard output:", err)}err = cmd.Wait()if err != nil {fmt.Println("Error waiting for command to finish:", err)}
}
修改程序:
package mainimport ("bufio""fmt""io""log""os/exec"
)func getReaderSize(rd io.Reader) {b, ok := rd.(*bufio.Reader)if ok {log.Printf("rd size: %d", b.Size())} else {log.Printf("rd is not bufio.Reader")}
}func main() {// Command to executecmd := exec.Command("./test")// Create a pipe to capture the standard output of the commandstdout, err := cmd.StdoutPipe()if err != nil {fmt.Println("Error creating StdoutPipe:", err)return}cmd.Stderr = cmd.Stdout// Start the commanderr = cmd.Start()if err != nil {fmt.Println("Error starting command:", err)return} Create a scanner to read the command's standard output//scanner := bufio.NewScanner(stdout)//scanner.Split(bufio.ScanBytes)// Read and print each line from the output//buf := make([]byte, 256)//bufLen := 0//for scanner.Scan() {// buf[bufLen] = scanner.Bytes()[0]// // buf = append(buf, scanner.Bytes()...)// bufLen += 1// if buf[bufLen-1] == '\n' || bufLen >= 256 {// log.Printf("%s", string(buf[:bufLen]))// bufLen = 0// }//}// Check for errors in scanning//if err := scanner.Err(); err != nil {// fmt.Println("Error reading standard output:", err)//}// Create a buffered reader to read from the command's stdoutreader := bufio.NewReaderSize(stdout, 256)getReaderSize(stdout)log.Printf("reader size: %d", reader.Size()) Buffer to store incomplete lines//var incompleteLine []byte// Buffer to read chunks of bytes//chunk := make([]byte, 256)////for {// // Read a chunk of bytes// n, err := reader.Read(chunk)// if err != nil {// break // Break the loop when an error occurs (e.g., when the command finishes)// }//// // Process each byte in the chunk// for i := 0; i < n; i++ {// b := chunk[i]//// // Check for newline or length exceeding 256// if b == '\n' || len(incompleteLine) >= 256 {// // Print the line// log.Printf("%s", incompleteLine)//// // Reset the incomplete line buffer// incompleteLine = nil// } else {// // Add the byte to the incomplete line buffer// incompleteLine = append(incompleteLine, b)// }// }//}for {s, err := reader.ReadSlice('\n')if err != nil && err != bufio.ErrBufferFull {if len(s) > 0 {log.Printf("reader err but exist data, reader size: %d, read string size: %d, string: %s", reader.Size(), len(s), string(s))}fmt.Println("Error reader ReadString:", err)break // Break the loop when an error occurs (e.g., when the command finishes)}log.Printf("reader size: %d, read string size: %d, string: %s", reader.Size(), len(s), string(s))}// Wait for the command to finisherr = cmd.Wait()if err != nil {fmt.Println("Error waiting for command to finish:", err)}
}
benchmark test:
package mainimport ("strconv""strings""testing"
)func stringTest1() string {var buf stringfor i := 0; i < 256; i++ {buf += strconv.Itoa(i)}return buf
}func stringTest2() string {var buf strings.Builderfor i := 0; i < 256; i++ {buf.Write([]byte(strconv.Itoa(i)))}return buf.String()
}func stringTest3() string {var buf = make([]byte, 0)for i := 0; i < 256; i++ {buf = append(buf, []byte(strconv.Itoa(i))...)}return string(buf)
}func stringTest4() string {var buf = make([]byte, 256)for i := 0; i < 256; i++ {buf[i] = '1'}return string(buf)
}func BenchmarkStringTest1(b *testing.B) {for i := 0; i < b.N; i++ {stringTest1()}
}
func BenchmarkStringTest2(b *testing.B) {for i := 0; i < b.N; i++ {stringTest2()}
}
func BenchmarkStringTest3(b *testing.B) {for i := 0; i < b.N; i++ {stringTest3()}
}
func BenchmarkStringTest4(b *testing.B) {for i := 0; i < b.N; i++ {stringTest4()}
}
benchmark test
cmd:
go test -bench . -benchmem
go test -bench=<function>
相关文章:
go 问题记录(日志丢失)
问题描述: 在go程序中,通过执行一个命令启动一个子命令,并通过pipe读取子程序的标准输入和输出,通过scanner默认按行读取,此时如果子程序输出时没有携带’\n’,scanner就不会打印输出,而是会累…...
彻底解决 MAC Android Studio gradle async 时出现 “connect timed out“ 问题
最近在编译一个比较老的项目,git clone 之后使用 async 之后出现一下现象: 首先确定是我网络本身是没有问题的,尝试几次重新 async 之后还是出现问题,网上找了一些方法解决了本问题,以此来记录一下问题是如何解决的。 …...
计算机网络第4章(网络层)
4.1、网络层概述 简介 网络层的主要任务是实现网络互连,进而实现数据包在各网络之间的传输 这些异构型网络N1~N7如果只是需要各自内部通信,他们只要实现各自的物理层和数据链路层即可 但是如果要将这些异构型网络互连起来,形成一个更大的互…...
SpringbootWeb案例
准备工作 需求说明 部门管理 部门管理功能开发包括:查询部门列表、删除部门、新增部门、修改部门 员工管理功能开发包括:查询员工列表(分页、条件)、删除员工、新增员工、修改员工 环境搭建 环境搭建步骤:1. 准备数据库表(dept、emp)…...
【初中生讲机器学习】4. 支持向量机算法怎么用?一个实例带你看懂!
创建时间:2024-02-02 最后编辑时间:2024-02-03 作者:Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏,很高兴遇见你~ 我是 Geeker_LStar,一名初三学生,热爱计算机和数学,我们一起加…...
CentOS下安装vlc
一、引言 vlc是一跨多媒体播放器,可以播放本地媒体文件和网络串流,帮助我们排查音视频开发过程中遇到的问题。大部分情况下,我们只需要在Windows系统下安装vlc就可以了。但有一种情况是需要在Linux下安装vlc的:我们的音视频拉流软…...
概率论中的全概率公式、贝叶斯公式解析
全概率公式 定义 全概率公式是用来计算一个事件的概率,这个事件可以通过几个互斥事件的并集来表示。这几个互斥事件称为“完备事件系”。实质是由原因推结果。 公式 用途 全概率公式通常用于计算一个事件的总概率,特别是当这个事件与几个不同的因素相关…...
亿赛通-数据泄露防护(DLP)UploadFileList;login接口存在任意文件读取漏洞 附POC软件
@[toc] 亿赛通-数据泄露防护(DLP)UploadFileList;login接口存在任意文件读取漏洞 附POC软件 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文…...
如何使用 Google 搜索引擎保姆级教程(附链接)
一、介绍 "Google语法"通常是指在 Google 搜索引擎中使用一系列特定的搜索语法和操作符来精确地定义搜索查询。这些语法和操作符允许用户过滤和调整搜索结果,提高搜索的准确性。 二、安装 Google 下载 Google 浏览器 Google 官网https://www.google.c…...
SpringBoot实现轻量级接口反向代理、转发
目录 1、基本的对象1.1 配置类1.2 实体DTO1.3 路由代理拓展器1.4 请求对象 RestTemplate 2、核心转发代码3、暴露接口4、基础配置 前言:想实现一个轻量级的接口反向代理和转发的一个接口服务,可以通过这个服务做一些需要认证才能访问的接口给到前端使用&…...
算法训练营day21,回溯1
77. 组合 func combine(n int, k int) [][]int { //存储全部集合 result : make([][]int, 0) //存储单次集合 path : make([]int, 0) var backtrace func(n int, k int, startIndex int) backtrace func(n int, k int, startIndex int) { //当单次集合大小和k值相等ÿ…...
延伸与应用(三)婚姻与经济、运动、宗教、科技与经济
53.幸福婚姻的经济ABC方程式 夫以信先其妇,则妇以信顺其夫。上秉常以化下,下服常而应上,其不化者,百未有一也。 ——《傅子》,傅玄(217—278) 在现代的小家庭中,由于家庭…...
mac上,配置bundletool,将aab转为apk
1.第一步打开终端,安装brew 2.安装bundletool brew install bundletool 3.aab转apk bundletool build-apks --bundle/MyApp/my_app.aab --output/MyApp/my_app.apks 如果下载了bundletool--xxx.jar,脚本命令前加 java -jar bundletool-all-1.5.0.j…...
wangEditor v4的简单使用
当前文档是 wangEditor v4 版本的。 wangEditor v5 已经正式发布,可参考文档。 v5 发布之后,v4 将不再开发新功能。 介绍 English documentation wangEditor4 —— 轻量级 web 富文本编辑器,配置方便,使用简单。 官网&#…...
简单实践 java spring boot 自动配置模拟
1.概要 1.1 需求,自己写一个redis-spring-boot-starter模拟自动配置 自动配置就是在引入*-starter坐标后,可以已经spring框架的规则实现一些Bean的自动注入,并设置一些参数的默认值,且也可以在引入的工程中修改这些配置的值。这…...
BeanDefinition学习
Spring版本5.1.x Spring中的BeanDefinition是一个接口,用于描述Spring容器中Bean的元数据。BeanDefinition描述了Bean的各种属性,如名称、依赖关系、初始化方法等。这个接口通常用于在Spring的IoC容器中注册Bean,并且当容器需要创建Bean实例…...
ASP.NET的GridView控件中,实现同列内容合并
在ASP.NET的GridView控件中,实现同列内容合并的方法主要有两种:一种是使用RowDataBound事件,另一种是使用自定义定义函数 使用RowDataBound事件 这种方法是在GridView的每一行绑定数据时,比较当前行和前一行的同一列的值&#x…...
【文本到上下文 #8】NLP中的变形金刚:解码游戏规则改变者
一、说明 欢迎来到我们对不断发展的自然语言处理 (NLP) 领域的探索的第 8 章。在本期中,我们将重点介绍一项重塑 NLP 格局的突破性创新:Transformers。在我们之前对 seq2seq 模型、编码器-解码器框架和注意力机制的讨论之后&#…...
mysql主流版本5.5/5.6/5.7/8.0重置修改密码方法
最近几天来回切换各个Mysql版本重置密码,记录一下各个版本重置密码的方法。 MySql 5.5 SET PASSWORD FOR usernamelocalhost PASSWORD(new_password);MySql5.6 SET PASSWORD FOR usernamelocalhost new_password;MySql5.7 ALTER USER usernamelocalhost IDENT…...
设计模式——备忘录模式
跟多内容,前往IT-BLOG 备忘录模式(Memento Pattern): 保存对象的某个状态,以便在未来需要的时候进行数据的恢复。相当容易理解,举个简单的例子:Word 软件在编辑时按 CtrlZ 组合键时能撤销当…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
