@@ -4,10 +4,12 @@ import (
4
4
"context"
5
5
"errors"
6
6
"fmt"
7
+ "log/slog"
7
8
"os"
8
9
"os/signal"
9
10
"runtime"
10
11
"runtime/debug"
12
+ "strings"
11
13
"sync"
12
14
"syscall"
13
15
"time"
@@ -20,11 +22,10 @@ import (
20
22
"github.com/digineo/texd/refstore/nop"
21
23
"github.com/digineo/texd/service"
22
24
"github.com/digineo/texd/tex"
25
+ "github.com/digineo/texd/xlog"
23
26
"github.com/docker/go-units"
24
27
"github.com/spf13/pflag"
25
28
"github.com/thediveo/enumflag"
26
- "go.uber.org/zap"
27
- "go.uber.org/zap/zapcore"
28
29
)
29
30
30
31
var opts = service.Options {
42
43
engine = tex .DefaultEngine .Name ()
43
44
jobdir = ""
44
45
pull = false
45
- logLevel = zapcore . InfoLevel .String ()
46
+ logLevel = slog . LevelInfo .String ()
46
47
maxJobSize = units .BytesSize (float64 (opts .MaxJobSize ))
47
48
storageDSN = ""
48
49
showVersion = false
@@ -108,7 +109,7 @@ func parseFlags() []string {
108
109
fmt .Sprintf ("enable reference store and configure with `DSN`, available adapters are: %v" , refstore .AvailableAdapters ()))
109
110
fs .BoolVar (& pull , "pull" , pull , "always pull Docker images" )
110
111
fs .StringVar (& logLevel , "log-level" , logLevel ,
111
- "set logging verbosity, acceptable values are: [debug, info, warn, error, dpanic, panic, fatal]" )
112
+ "set logging verbosity, acceptable values are: [debug, info, warn, error, fatal]" )
112
113
fs .BoolVarP (& showVersion , "version" , "v" , showVersion ,
113
114
`print version information and exit` )
114
115
@@ -137,8 +138,10 @@ func parseFlags() []string {
137
138
func main () {
138
139
texd .PrintBanner (os .Stdout )
139
140
images := parseFlags () //nolint:ifshort // func has sideeffects
140
- log , sync := setupLogger ()
141
- defer sync ()
141
+ log , err := setupLogger ()
142
+ if err != nil {
143
+ panic (err )
144
+ }
142
145
143
146
if showVersion {
144
147
printVersion ()
@@ -147,32 +150,32 @@ func main() {
147
150
148
151
if err := tex .SetJobBaseDir (jobdir ); err != nil {
149
152
log .Fatal ("error setting job directory" ,
150
- zap .String ("flag" , "--job-directory" ),
151
- zap .Error (err ))
153
+ xlog .String ("flag" , "--job-directory" ),
154
+ xlog .Error (err ))
152
155
}
153
156
if err := tex .SetDefaultEngine (engine ); err != nil {
154
157
log .Fatal ("error setting default TeX engine" ,
155
- zap .String ("flag" , "--tex-engine" ),
156
- zap .Error (err ))
158
+ xlog .String ("flag" , "--tex-engine" ),
159
+ xlog .Error (err ))
157
160
}
158
161
if max , err := units .FromHumanSize (maxJobSize ); err != nil {
159
162
log .Fatal ("error parsing maximum job size" ,
160
- zap .String ("flag" , "--max-job-size" ),
161
- zap .Error (err ))
163
+ xlog .String ("flag" , "--max-job-size" ),
164
+ xlog .Error (err ))
162
165
} else {
163
166
opts .MaxJobSize = max
164
167
}
165
168
if storageDSN != "" {
166
169
rp , err := retentionPolicy ()
167
170
if err != nil {
168
171
log .Fatal ("error initializing retention policy" ,
169
- zap .String ("flag" , "--retention-policy, and/or --rp-access-items, --rp-access-size" ),
170
- zap .Error (err ))
172
+ xlog .String ("flag" , "--retention-policy, and/or --rp-access-items, --rp-access-size" ),
173
+ xlog .Error (err ))
171
174
}
172
175
if adapter , err := refstore .NewStore (storageDSN , rp ); err != nil {
173
176
log .Fatal ("error parsing reference store DSN" ,
174
- zap .String ("flag" , "--reference-store" ),
175
- zap .Error (err ))
177
+ xlog .String ("flag" , "--reference-store" ),
178
+ xlog .Error (err ))
176
179
} else {
177
180
opts .RefStore = adapter
178
181
}
@@ -181,23 +184,25 @@ func main() {
181
184
}
182
185
183
186
if len (images ) > 0 {
184
- log .Info ("using docker" , zap . Strings ("images" , images ))
187
+ log .Info ("using docker" , xlog . String ("images" , strings . Join ( images , "," ) ))
185
188
cli , err := exec .NewDockerClient (log , tex .JobBaseDir ())
186
189
if err != nil {
187
- log .Fatal ("error connecting to dockerd" , zap .Error (err ))
190
+ log .Error ("error connecting to dockerd" , xlog .Error (err ))
191
+ os .Exit (1 )
188
192
}
189
193
190
194
opts .Images , err = cli .SetImages (context .Background (), pull , images ... )
191
195
opts .Mode = "container"
192
196
if err != nil {
193
- log .Fatal ("error setting images" , zap .Error (err ))
197
+ log .Error ("error setting images" , xlog .Error (err ))
198
+ os .Exit (1 )
194
199
}
195
200
opts .Executor = cli .Executor
196
201
}
197
202
198
203
stop , err := service .Start (opts , log )
199
204
if err != nil {
200
- log .Fatal ("failed to start service" , zap .Error (err ))
205
+ log .Fatal ("failed to start service" , xlog .Error (err ))
201
206
}
202
207
onExit (log , stop )
203
208
}
@@ -206,14 +211,14 @@ const exitTimeout = 10 * time.Second
206
211
207
212
type stopFun func (context.Context ) error
208
213
209
- func onExit (log * zap .Logger , stopper ... stopFun ) {
214
+ func onExit (log xlog .Logger , stopper ... stopFun ) {
210
215
exitCh := make (chan os.Signal , 2 )
211
216
signal .Notify (exitCh , syscall .SIGINT , syscall .SIGTERM )
212
217
sig := <- exitCh
213
218
214
219
log .Info ("performing shutdown, press Ctrl+C to exit now" ,
215
- zap .String ("signal" , sig .String ()),
216
- zap .Duration ("graceful-wait-timeout" , exitTimeout ))
220
+ xlog .String ("signal" , sig .String ()),
221
+ slog .Duration ("graceful-wait-timeout" , exitTimeout ))
217
222
218
223
ctx , cancel := context .WithTimeout (context .Background (), exitTimeout )
219
224
defer cancel ()
@@ -223,7 +228,7 @@ func onExit(log *zap.Logger, stopper ...stopFun) {
223
228
for _ , stop := range stopper {
224
229
go func (f stopFun ) {
225
230
if err := f (ctx ); err != nil {
226
- log .Error ("error while shutting down" , zap .Error (err ))
231
+ log .Error ("error while shutting down" , xlog .Error (err ))
227
232
}
228
233
wg .Done ()
229
234
}(stop )
@@ -266,34 +271,20 @@ func printVersion() {
266
271
}
267
272
}
268
273
269
- func setupLogger () (* zap.Logger , func ()) {
270
- var cfg zap.Config
271
- if texd .Development () {
272
- cfg = zap .NewDevelopmentConfig ()
273
- } else {
274
- cfg = zap .NewProductionConfig ()
275
- }
276
-
277
- lvl , lvlErr := zapcore .ParseLevel (logLevel )
278
- if lvlErr == nil {
279
- cfg .Level = zap .NewAtomicLevelAt (lvl )
280
- }
281
-
282
- log , err := cfg .Build ()
274
+ func setupLogger () (xlog.Logger , error ) {
275
+ lvl , err := xlog .ParseLevel (logLevel )
283
276
if err != nil {
284
- // we don't have a logger yet, so logging the error
285
- // proves to be complicated :)
286
- panic (err )
277
+ return nil , err
287
278
}
288
279
289
- if lvlErr != nil {
290
- log . Error ( "error parsing log level" ,
291
- zap . String ( "flag" , "--log-level" ),
292
- zap . Error ( lvlErr ))
280
+ o := & slog. HandlerOptions {
281
+ AddSource : true ,
282
+ // XXX: provide ReplaceAttr callback to normalize Source locations?
283
+ Level : lvl ,
293
284
}
294
285
295
- zap .ReplaceGlobals (log )
296
- return log , func () {
297
- _ = log .Sync ()
286
+ if texd .Development () {
287
+ return xlog .New (xlog .TypeText , os .Stderr , o )
298
288
}
289
+ return xlog .New (xlog .TypeJSON , os .Stdout , o )
299
290
}
0 commit comments