github.com/benz9527/xboot@v0.0.0-20240504061247-c23f15593274/xlog/file_core_test.go (about) 1 package xlog 2 3 import ( 4 "archive/zip" 5 "context" 6 "os" 7 "path/filepath" 8 "strconv" 9 "testing" 10 "time" 11 12 "github.com/stretchr/testify/require" 13 "go.uber.org/zap" 14 "go.uber.org/zap/zapcore" 15 16 "github.com/benz9527/xboot/lib/id" 17 ) 18 19 func TestXLogFileCore_RotateLog(t *testing.T) { 20 nano, err := id.ClassicNanoID(6) 21 require.NoError(t, err) 22 rngLogSuffix := "_" + nano() + "_xlog" 23 rngLogZipSuffix := rngLogSuffix + "s" 24 lvlEnabler := zap.NewAtomicLevelAt(LogLevelDebug.zapLevel()) 25 cfg := &FileCoreConfig{ 26 FilePath: os.TempDir(), 27 Filename: filepath.Base(os.Args[0]) + rngLogSuffix + ".log", 28 FileCompressible: true, 29 FileMaxBackups: 4, 30 FileMaxAge: "3day", 31 FileMaxSize: "1KB", 32 FileCompressBatch: 2, 33 FileZipName: filepath.Base(os.Args[0]) + rngLogZipSuffix + ".zip", 34 FileRotateEnable: true, 35 FileBufferSize: "1KB", 36 FileBufferFlushInterval: 500, 37 } 38 39 ctx, cancel := context.WithCancel(context.TODO()) 40 cc := newFileCore(cfg)( 41 nil, 42 &lvlEnabler, 43 JSON, 44 zapcore.CapitalLevelEncoder, 45 zapcore.ISO8601TimeEncoder, 46 ) 47 require.Nil(t, cc) 48 49 cc = newFileCore(cfg)( 50 ctx, 51 &lvlEnabler, 52 JSON, 53 zapcore.CapitalLevelEncoder, 54 zapcore.ISO8601TimeEncoder, 55 ) 56 57 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 58 for i := 0; i < 100; i++ { 59 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog rolling log write test!")}) 60 require.NoError(t, err) 61 } 62 time.Sleep(1 * time.Second) 63 err = cc.Sync() 64 require.NoError(t, err) 65 cancel() 66 67 reader, err := zip.OpenReader(filepath.Join(cfg.FilePath, cfg.FileZipName)) 68 require.NoError(t, err) 69 require.GreaterOrEqual(t, len(reader.File), cfg.FileCompressBatch) 70 err = reader.Close() 71 require.NoError(t, err) 72 73 removed := testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogSuffix, ".log") 74 require.GreaterOrEqual(t, removed, cfg.FileMaxBackups+1) 75 removed = testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogZipSuffix, ".zip") 76 require.Equal(t, removed, 1) 77 } 78 79 func TestXLogFileCore_SingleLog(t *testing.T) { 80 nano, err := id.ClassicNanoID(6) 81 require.NoError(t, err) 82 rngLogSuffix := "_" + nano() + "_xlog" 83 rngLogZipSuffix := rngLogSuffix + "s" 84 lvlEnabler := zap.NewAtomicLevelAt(LogLevelDebug.zapLevel()) 85 cfg := &FileCoreConfig{ 86 FilePath: os.TempDir(), 87 Filename: filepath.Base(os.Args[0]) + rngLogSuffix + ".log", 88 } 89 90 ctx, cancel := context.WithCancel(context.TODO()) 91 cc := newFileCore(cfg)( 92 nil, 93 &lvlEnabler, 94 JSON, 95 zapcore.CapitalLevelEncoder, 96 zapcore.ISO8601TimeEncoder, 97 ) 98 require.Nil(t, cc) 99 100 cc = newFileCore(cfg)( 101 ctx, 102 &lvlEnabler, 103 JSON, 104 zapcore.CapitalLevelEncoder, 105 zapcore.ISO8601TimeEncoder, 106 ) 107 108 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 109 for i := 0; i < 100; i++ { 110 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog single log write test!")}) 111 require.NoError(t, err) 112 } 113 time.Sleep(1 * time.Second) 114 err = cc.Sync() 115 require.NoError(t, err) 116 cancel() 117 118 removed := testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogSuffix, ".log") 119 require.GreaterOrEqual(t, removed, cfg.FileMaxBackups+1) 120 removed = testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogZipSuffix, ".zip") 121 require.Equal(t, 0, removed) 122 } 123 124 func TestXLogFileCore_RotateLog_DataRace(t *testing.T) { 125 nano, err := id.ClassicNanoID(6) 126 require.NoError(t, err) 127 rngLogSuffix := "_" + nano() + "_xlog" 128 rngLogZipSuffix := rngLogSuffix + "s" 129 lvlEnabler := zap.NewAtomicLevelAt(LogLevelDebug.zapLevel()) 130 cfg := &FileCoreConfig{ 131 FilePath: os.TempDir(), 132 Filename: filepath.Base(os.Args[0]) + rngLogSuffix + ".log", 133 FileCompressible: true, 134 FileMaxBackups: 4, 135 FileMaxAge: "3day", 136 FileMaxSize: "1KB", 137 FileCompressBatch: 2, 138 FileZipName: filepath.Base(os.Args[0]) + rngLogZipSuffix + ".zip", 139 FileRotateEnable: true, 140 FileBufferSize: "1KB", 141 FileBufferFlushInterval: 500, 142 } 143 144 ctx, cancel := context.WithCancel(context.TODO()) 145 cc := newFileCore(cfg)( 146 nil, 147 &lvlEnabler, 148 JSON, 149 zapcore.CapitalLevelEncoder, 150 zapcore.ISO8601TimeEncoder, 151 ) 152 require.Nil(t, cc) 153 154 cc = newFileCore(cfg)( 155 ctx, 156 &lvlEnabler, 157 JSON, 158 zapcore.CapitalLevelEncoder, 159 zapcore.ISO8601TimeEncoder, 160 ) 161 162 go func() { 163 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 164 for i := 0; i < 100; i++ { 165 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog rolling log write test!")}) 166 require.NoError(t, err) 167 } 168 }() 169 go func() { 170 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 171 for i := 100; i < 200; i++ { 172 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog rolling log write test!")}) 173 require.NoError(t, err) 174 } 175 }() 176 177 time.Sleep(1 * time.Second) 178 err = cc.Sync() 179 require.NoError(t, err) 180 cancel() 181 182 reader, err := zip.OpenReader(filepath.Join(cfg.FilePath, cfg.FileZipName)) 183 require.NoError(t, err) 184 require.GreaterOrEqual(t, len(reader.File), cfg.FileCompressBatch) 185 err = reader.Close() 186 require.NoError(t, err) 187 removed := testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogSuffix, ".log") 188 require.GreaterOrEqual(t, removed, cfg.FileMaxBackups+1) 189 removed = testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogZipSuffix, ".zip") 190 require.Equal(t, removed, 1) 191 } 192 193 func TestXLogFileCore_SingleLog_DataRace(t *testing.T) { 194 nano, err := id.ClassicNanoID(6) 195 require.NoError(t, err) 196 rngLogSuffix := "_" + nano() + "_xlog" 197 lvlEnabler := zap.NewAtomicLevelAt(LogLevelDebug.zapLevel()) 198 cfg := &FileCoreConfig{ 199 FilePath: os.TempDir(), 200 Filename: filepath.Base(os.Args[0]) + rngLogSuffix + ".log", 201 } 202 203 ctx, cancel := context.WithCancel(context.TODO()) 204 cc := newFileCore(cfg)( 205 nil, 206 &lvlEnabler, 207 JSON, 208 zapcore.CapitalLevelEncoder, 209 zapcore.ISO8601TimeEncoder, 210 ) 211 require.Nil(t, cc) 212 213 cc = newFileCore(cfg)( 214 ctx, 215 &lvlEnabler, 216 JSON, 217 zapcore.CapitalLevelEncoder, 218 zapcore.ISO8601TimeEncoder, 219 ) 220 221 go func() { 222 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 223 for i := 0; i < 100; i++ { 224 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog single log write test!")}) 225 require.NoError(t, err) 226 } 227 }() 228 go func() { 229 ent := cc.Check(zapcore.Entry{Level: zapcore.DebugLevel}, nil) 230 for i := 100; i < 200; i++ { 231 err := cc.Write(ent.Entry, []zap.Field{zap.String("key", strconv.Itoa(i)+" "+time.Now().UTC().Format(backupDateTimeFormat)+" xlog single log write test!")}) 232 require.NoError(t, err) 233 } 234 }() 235 236 time.Sleep(1 * time.Second) 237 err = cc.Sync() 238 require.NoError(t, err) 239 cancel() 240 241 removed := testCleanLogFiles(t, os.TempDir(), filepath.Base(os.Args[0])+rngLogSuffix, ".log") 242 require.GreaterOrEqual(t, removed, 1) 243 }