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  }