日志是应用的镜子,可以发现应用中的问题,重要性不言而喻。
以往设备有问题了,是如何诊断的?我们是现场人员到现场,又是配合抓包,又是配合提供机器日志,效率极其低下。
如今都物联网时代了,能让数据跑路的还让人去跑路,不合适吧。
日志应能实现手工触发上送,或应用中出现严重问题时主动上送,或者远程控制其是否上送。
试想,如果能让问题出现在被客户发现之前,提前被开发人员获知,主动的解决问题,那么无疑提高了产品的竞争力和口碑。为杜绝问题造成的严重性而未及时发现提供先机。
当某天发现一机器偶然吐出一异常的bug日志时,且这日志暴露的问题若不解决将造成严重后果,而你恰好在你的邮箱里看到,这就在不知不觉中主动发现了问题。不用运维人员去找你,客户去找你,机器向你求救了。那么,救救它吧。
以下为在嵌入式linux上实现的一小功能,对终端产生的日志文件进行zip压缩并上送到后台FTP服务器中。
几行代码,轻松实现。又一次体现使用 go开发嵌入式linux应用的强大之处。
若要用c去做,那么呵呵,可以试试。
package main import ( "archive/zip" "flag" "fmt" "io" "log" "os" "strings" "github.com/dutchcoders/goftp" "github.com/larspensjo/config" ) var ( ftp *goftp.FTP conFile = flag.String("ftpcfg", "/ftpcfg.ini", "config file") Server string = "127.0.0.1:21" User string = "" Pwd string = "" ) func checkErr(err error) { if err != nil { fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error()) } } /** @files:需要压缩的文件 @compreFile:压缩之后的文件 */ func CompressZip(files []*os.File, zipfileName string) (err error) { zipfile, err := os.Create(zipfileName) if err != nil { return err } defer zipfile.Close() zw := zip.NewWriter(zipfile) defer zw.Close() for _, file := range files { err := compressZip(file, zw) if err != nil { return err } file.Close() } return nil } /** 功能:压缩文件 @file:压缩文件 @prefix:压缩文件内部的路径 @tw:写入压缩文件的流 */ func compressZip(file *os.File, zw *zip.Writer) error { info, err := file.Stat() if err != nil { log.Println("压缩文件失败:", err.Error()) return err } log.Println("filesize:", info.Size()/1024, "kb") // 获取压缩头信息 head, err := zip.FileInfoHeader(info) if err != nil { log.Println("压缩文件失败:", err.Error()) return err } // 指定文件压缩方式 默认为 Store 方式 该方式不压缩文件 只是转换为zip保存 head.Method = zip.Deflate fw, err := zw.CreateHeader(head) if err != nil { log.Println("压缩文件失败:", err.Error()) return err } // 写入文件到压缩包中 _, err = io.Copy(fw, file) file.Close() if err != nil { log.Println("压缩文件失败:", err.Error()) return err } return nil } func main() { log.Println("Hello Go") defer func() { if r := recover(); r != nil { log.Printf("crash occurred!capture:%s\n", r) } }() var fname string flag.StringVar(&fname, "fname", "", "file name") flag.Parse() flag.Usage() //获取当前路径 file, _ := os.Getwd() cfg, err := config.ReadDefault(file + *conFile) checkErr(err) //获取配置文件中的配置项 Server, err = cfg.String("SERVERCONFIG", "Server") User, err = cfg.String("USER", "User") Pwd, err = cfg.String("USER", "Pwd") //压缩ZIP var filezips []*os.File var filezip *os.File if filezip, err = os.Open(fname); err != nil { panic(err) } filezips = append(filezips, filezip) log.Println("begin compressZip...") err = CompressZip(filezips, fname+".zip") if err != nil { panic(err) } log.Println("compressZip ok!,name=" + fname + ".zip") log.Println("User:" + User) log.Println("->begin connect server:" + Server) // For debug messages: goftp.ConnectDbg("ftp.server.com:21") if ftp, err = goftp.ConnectDbg(Server); err != nil { panic(err) } //ftp.debug = true defer ftp.Close() log.Println("->Successfully connected !!") // Username / password authentication if err = ftp.Login(User, Pwd); err != nil { panic(err) } log.Println("->Login success!") if err = ftp.Cwd("/"); err != nil { panic(err) } var curpath string if curpath, err = ftp.Pwd(); err != nil { panic(err) } log.Printf("Current path: %s\n", curpath) // Upload a file var fileup *os.File if fileup, err = os.Open(fname + ".zip"); err != nil { panic(err) } log.Println("->begin upload file...") info, err := fileup.Stat() if err != nil { panic(err) } log.Println("upload filesize:", info.Size()/1024, "kb") fpath := fname + ".zip" lastidx := strings.LastIndex(fname+".zip", "/") if lastidx != -1 { fpath = fname[lastidx:] + ".zip" } log.Printf("fpath:%s\n", fpath) if err := ftp.Stor(fpath, fileup); err != nil { panic(err) } log.Println("->upload file over!") err = os.Remove(fname + ".zip") //上传成功,删除zip文件 if err != nil { log.Println("file remove Error!") panic(err) } }
编译与使用:
GOOS=linux GOARCH=arm GOARM=7 go build ftp.go ftp -fname=/log/log_b503_20190730.log root@b_lcd:/app/opt ./ftp -fname=/log/log_b503_20190730.log Hello Go Usage of ./ftp: -fname string file name -ftpcfg string config file (default "/ftpcfg.ini") User:qq8864 ->begin connect server:015.3vftp.com:21 2019/07/30 17:44:08 begin receiveLine... 2019/07/30 17:44:09 < 220 Serv-U FTP Server v6.4 for WinSock ready... 2019/07/30 17:44:09 receiveLine over! 2019/07/30 17:44:09 220 Serv-U FTP Server v6.4 for WinSock ready... ->Successfully connected !! 2019/07/30 17:44:09 > USER qq8864 2019/07/30 17:44:09 begin receiveLine... 2019/07/30 17:44:09 < 331 User name okay, need password. 2019/07/30 17:44:09 receiveLine over! 2019/07/30 17:44:09 > PASS sars1212 2019/07/30 17:44:09 begin receiveLine... 2019/07/30 17:44:09 < 230 User logged in, proceed. 2019/07/30 17:44:09 receiveLine over! ->Login success! 2019/07/30 17:44:09 > CWD / 2019/07/30 17:44:09 begin receiveLine... 2019/07/30 17:44:09 < 250 Directory changed to / 2019/07/30 17:44:09 receiveLine over! 2019/07/30 17:44:09 > PWD 2019/07/30 17:44:09 begin receiveLine... 2019/07/30 17:44:09 < 257 "/" is current directory. 2019/07/30 17:44:09 receiveLine over! Current path: / ->begin upload file... fpath:/log_b503_20190730.log 2019/07/30 17:44:09 > TYPE I 2019/07/30 17:44:09 begin receiveLine... 2019/07/30 17:44:11 < 200 Type set to I. 2019/07/30 17:44:11 receiveLine over! 2019/07/30 17:44:11 > PASV 2019/07/30 17:44:11 begin receiveLine... 2019/07/30 17:44:11 < 227 Entering Passive Mode (52,128,243,181,6,1) 2019/07/30 17:44:11 receiveLine over! 2019/07/30 17:44:11 > STOR /log_b503_20190730.log 2019/07/30 17:44:11 Connecting to 015.3vftp.com:1537 2019/07/30 17:44:11 begin receiveLine... 2019/07/30 17:44:11 < 150 Opening BINARY mode data connection for log_b503_20190730.log. 2019/07/30 17:44:11 receiveLine over! 2019/07/30 17:44:11 a1:150 Opening BINARY mode data connection for log_b503_20190730.log. 2019/07/30 17:44:11 begin receiveLine... 2019/07/30 17:44:13 < 226-Maximum disk quota limited to 102400 kBytes 2019/07/30 17:44:13 receiveLine over! 2019/07/30 17:44:13 begin receiveLine... 2019/07/30 17:44:13 < Used disk quota 64 kBytes, available 102335 kBytes 2019/07/30 17:44:13 receiveLine over! 2019/07/30 17:44:13 begin receiveLine... 2019/07/30 17:44:13 < 226 Transfer complete. 2019/07/30 17:44:13 receiveLine over! 2019/07/30 17:44:13 a2:226-Maximum disk quota limited to 102400 kBytes Used disk quota 64 kBytes, available 102335 kBytes 226 Transfer complete. ->upload file over!