github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/debuglog_db.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver 5 6 import ( 7 "fmt" 8 "net/http" 9 "time" 10 11 "github.com/juju/errors" 12 13 "github.com/juju/juju/state" 14 ) 15 16 func newDebugLogDBHandler(ctxt httpContext) http.Handler { 17 return newDebugLogHandler(ctxt, handleDebugLogDBRequest) 18 } 19 20 func handleDebugLogDBRequest( 21 st state.LoggingState, 22 reqParams *debugLogParams, 23 socket debugLogSocket, 24 stop <-chan struct{}, 25 ) error { 26 params := makeLogTailerParams(reqParams) 27 tailer, err := newLogTailer(st, params) 28 if err != nil { 29 return errors.Trace(err) 30 } 31 defer tailer.Stop() 32 33 // Indicate that all is well. 34 socket.sendOk() 35 36 var lineCount uint 37 for { 38 select { 39 case <-stop: 40 return nil 41 case rec, ok := <-tailer.Logs(): 42 if !ok { 43 return errors.Annotate(tailer.Err(), "tailer stopped") 44 } 45 46 line := formatLogRecord(rec) 47 _, err := socket.Write([]byte(line)) 48 if err != nil { 49 return errors.Annotate(err, "sending failed") 50 } 51 52 lineCount++ 53 if reqParams.maxLines > 0 && lineCount == reqParams.maxLines { 54 return nil 55 } 56 } 57 } 58 } 59 60 func makeLogTailerParams(reqParams *debugLogParams) *state.LogTailerParams { 61 params := &state.LogTailerParams{ 62 MinLevel: reqParams.filterLevel, 63 NoTail: reqParams.noTail, 64 InitialLines: int(reqParams.backlog), 65 IncludeEntity: reqParams.includeEntity, 66 ExcludeEntity: reqParams.excludeEntity, 67 IncludeModule: reqParams.includeModule, 68 ExcludeModule: reqParams.excludeModule, 69 } 70 if reqParams.fromTheStart { 71 params.InitialLines = 0 72 } 73 return params 74 } 75 76 func formatLogRecord(r *state.LogRecord) string { 77 return fmt.Sprintf("%s: %s %s %s %s %s\n", 78 r.Entity, 79 formatTime(r.Time), 80 r.Level.String(), 81 r.Module, 82 r.Location, 83 r.Message, 84 ) 85 } 86 87 func formatTime(t time.Time) string { 88 return t.In(time.UTC).Format("2006-01-02 15:04:05") 89 } 90 91 var newLogTailer = _newLogTailer // For replacing in tests 92 93 func _newLogTailer(st state.LoggingState, params *state.LogTailerParams) (state.LogTailer, error) { 94 return state.NewLogTailer(st, params) 95 }