diff --git a/scalib/main.go b/scalib/main.go new file mode 100644 index 0000000..cf84aa9 --- /dev/null +++ b/scalib/main.go @@ -0,0 +1,92 @@ +package main + +import ( + "fmt" + "net/rpc" + "os" + "path/filepath" + "strings" + + "go.uber.org/zap" +) + +// FileInfo 包含文件的元信息 +type FileInfo struct { + FileName string + FileSize int64 +} + +// 客户端 +type UpFileClient struct { + rpcClient *rpc.Client +} + +// 主入口 +func main() { + // 将服务器的信息拆分为ip和端口 + harr := strings.Split(remote, ":") + dstip := harr[0] + dport := harr[1] + + // 连接到RPC服务器 + service := fmt.Sprintf("%v:%v", dstip, dport) + client, err := NewUpFileClient(service) + if err != nil { + logger.Error("NewUpFileClient failed", zap.Error(err)) + } + defer client.rpcClient.Close() + // 调用 transferFile + err = transferFile(client, filePath, uploadPath) + if err != nil { + logger.Error("TransferFile failed", zap.Error(err)) + fmt.Printf("TransferFile failed: %v\n", err) + } + fmt.Printf("TransferFile success\n") +} + +// 创建新的客户端 +func NewUpFileClient(addr string) (*UpFileClient, error) { + client, err := rpc.Dial("tcp", addr) + if err != nil { + return nil, err + } + return &UpFileClient{rpcClient: client}, nil +} + +// 传输文件 +func transferFile(c *UpFileClient, filePath string, uploadPath string) error { + + // 发送文件信息 + fmt.Printf("TransferFile filePath: %s, uploadPath: %s\n", filePath, uploadPath) + // 获取文件信息 + fileInfo, err := os.Stat(filePath) + if err != nil { + // panic(err) + fmt.Printf("获取文件信息失败: %v\n", err) + return err + } + + // 提取文件名 + // 远程的文件名 + fileName := filepath.Base(uploadPath) + fmt.Printf("fileName: %s\n", fileName) + + // 远程服务器的路径 + dirpath := filepath.Dir(uploadPath) + fmt.Printf("remote dirpath: %s\n", dirpath) + fmt.Printf("file size: %d\n", fileInfo.Size()) + + // 异步 + go func() { + // 发送文件信息 + var reply string + c.rpcClient.Call("UpFileService.SendFileInfo", FileInfo{ + FileName: uploadPath, + FileSize: fileInfo.Size(), + }, &reply) + // 输出执行的结果 + fmt.Printf("SendFileInfo result: %v\n", reply) + }() + + return nil +} diff --git a/scalib/util/xttlog.go b/scalib/util/xttlog.go new file mode 100644 index 0000000..a557e7a --- /dev/null +++ b/scalib/util/xttlog.go @@ -0,0 +1,70 @@ +package util + +import ( + "time" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "gopkg.in/natefinch/lumberjack.v2" +) + +// 初始化生产级日志器 +func NewProductionLogger() *zap.Logger { + // 1. 配置日志轮转(用lumberjack) + hook := &lumberjack.Logger{ + + Filename: "./logs/app.log", // 日志文件路径 + MaxSize: 10, // 单个文件最大大小(MB) + MaxBackups: 7, // 最多保留多少个备份文件 + MaxAge: 7, // 日志文件最多保留多少天 + Compress: true, // 是否压缩备份文件(gzip) + } + defer hook.Close() + + // 2. 设置日志输出格式 + // 时间格式:2024-05-20 09:30:00.123 + timeFormat := "2006-01-02 15:04:05.000" + encoderConfig := zapcore.EncoderConfig{ + TimeKey: "ts", + LevelKey: "level", + NameKey: "logger", + CallerKey: "caller", + MessageKey: "msg", + StacktraceKey: "stacktrace", + LineEnding: zapcore.DefaultLineEnding, + EncodeLevel: zapcore.CapitalLevelEncoder, // 级别用大写(INFO、ERROR) + EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) { + enc.AppendString(t.Format(timeFormat)) + }, + EncodeDuration: zapcore.SecondsDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, // 调用者信息简化(main/main.go:20) + } + + // 3. 配置日志级别和输出目标 + // 输出目标:同时打印到控制台和文件 + core := zapcore.NewCore( + zapcore.NewJSONEncoder(encoderConfig), // JSON格式 + zapcore.NewMultiWriteSyncer( + zapcore.AddSync(hook), // 写入文件 + //zapcore.AddSync(zapcore.Lock(os.Stdout)), // 打印到控制台 + ), + zapcore.InfoLevel, // 生产环境只打印Info及以上级别 + ) + + // 4. 开启调用者信息和堆栈跟踪 + logger := zap.New(core, + zap.AddCaller(), // 显示日志调用的文件和行号 + zap.AddStacktrace(zapcore.ErrorLevel), // 只有Error及以上级别才显示堆栈 + ) + + return logger +} + +// 根据环境初始化日志器 +func InitLogger(env string) *zap.Logger { + if env == "dev" { + logger, _ := zap.NewDevelopment() + return logger + } + return NewProductionLogger() +}