日誌是應用的鏡子,可以發現應用中的問題,重要性不言而喻。
以往設備有問題了,是如何診斷的?我們是現場人員到現場,又是配合抓包,又是配合提供機器日誌,效率極其低下。
如今都物聯網時代了,能讓數據跑路的還讓人去跑路,不合適吧。
日誌應能實現手工觸發上送,或應用中出現嚴重問題時主動上送,或者遠程控制其是否上送。
試想,如果能讓問題出現在被客戶發現之前,提前被開發人員獲知,主動的解決問題,那麼無疑提高了產品的競爭力和口碑。爲杜絕問題造成的嚴重性而未及時發現提供先機。
當某天發現一機器偶然吐出一異常的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!