Cleans up a whole bunch of things I wanted to get out of the door right away: * depot internal references to //third_party/nixery have been replaced with //tools/nixery * cleaned up files from Github * fixed SPDX & Copyright headers * code formatting and inclusion in //tools/depotfmt checks Change-Id: Iea79f0fdf3aa04f71741d4f4032f88605ae415bb Reviewed-on: https://cl.tvl.fyi/c/depot/+/5486 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: tazjin <tazjin@tvl.su>
		
			
				
	
	
		
			108 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2022 The TVL Contributors
 | 
						|
// SPDX-License-Identifier: Apache-2.0
 | 
						|
package logs
 | 
						|
 | 
						|
// This file configures different log formatters via logrus. The
 | 
						|
// standard formatter uses a structured JSON format that is compatible
 | 
						|
// with Stackdriver Error Reporting.
 | 
						|
//
 | 
						|
// https://cloud.google.com/error-reporting/docs/formatting-error-messages
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"encoding/json"
 | 
						|
	log "github.com/sirupsen/logrus"
 | 
						|
)
 | 
						|
 | 
						|
type stackdriverFormatter struct{}
 | 
						|
 | 
						|
type serviceContext struct {
 | 
						|
	Service string `json:"service"`
 | 
						|
	Version string `json:"version"`
 | 
						|
}
 | 
						|
 | 
						|
type reportLocation struct {
 | 
						|
	FilePath     string `json:"filePath"`
 | 
						|
	LineNumber   int    `json:"lineNumber"`
 | 
						|
	FunctionName string `json:"functionName"`
 | 
						|
}
 | 
						|
 | 
						|
var nixeryContext = serviceContext{
 | 
						|
	Service: "nixery",
 | 
						|
}
 | 
						|
 | 
						|
// isError determines whether an entry should be logged as an error
 | 
						|
// (i.e. with attached `context`).
 | 
						|
//
 | 
						|
// This requires the caller information to be present on the log
 | 
						|
// entry, as stacktraces are not available currently.
 | 
						|
func isError(e *log.Entry) bool {
 | 
						|
	l := e.Level
 | 
						|
	return (l == log.ErrorLevel || l == log.FatalLevel || l == log.PanicLevel) &&
 | 
						|
		e.HasCaller()
 | 
						|
}
 | 
						|
 | 
						|
// logSeverity formats the entry's severity into a format compatible
 | 
						|
// with Stackdriver Logging.
 | 
						|
//
 | 
						|
// The two formats that are being mapped do not have an equivalent set
 | 
						|
// of severities/levels, so the mapping is somewhat arbitrary for a
 | 
						|
// handful of them.
 | 
						|
//
 | 
						|
// https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#LogSeverity
 | 
						|
func logSeverity(l log.Level) string {
 | 
						|
	switch l {
 | 
						|
	case log.TraceLevel:
 | 
						|
		return "DEBUG"
 | 
						|
	case log.DebugLevel:
 | 
						|
		return "DEBUG"
 | 
						|
	case log.InfoLevel:
 | 
						|
		return "INFO"
 | 
						|
	case log.WarnLevel:
 | 
						|
		return "WARNING"
 | 
						|
	case log.ErrorLevel:
 | 
						|
		return "ERROR"
 | 
						|
	case log.FatalLevel:
 | 
						|
		return "CRITICAL"
 | 
						|
	case log.PanicLevel:
 | 
						|
		return "EMERGENCY"
 | 
						|
	default:
 | 
						|
		return "DEFAULT"
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (f stackdriverFormatter) Format(e *log.Entry) ([]byte, error) {
 | 
						|
	msg := e.Data
 | 
						|
	msg["serviceContext"] = &nixeryContext
 | 
						|
	msg["message"] = &e.Message
 | 
						|
	msg["eventTime"] = &e.Time
 | 
						|
	msg["severity"] = logSeverity(e.Level)
 | 
						|
 | 
						|
	if e, ok := msg[log.ErrorKey]; ok {
 | 
						|
		if err, isError := e.(error); isError {
 | 
						|
			msg[log.ErrorKey] = err.Error()
 | 
						|
		} else {
 | 
						|
			delete(msg, log.ErrorKey)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if isError(e) {
 | 
						|
		loc := reportLocation{
 | 
						|
			FilePath:     e.Caller.File,
 | 
						|
			LineNumber:   e.Caller.Line,
 | 
						|
			FunctionName: e.Caller.Function,
 | 
						|
		}
 | 
						|
		msg["context"] = &loc
 | 
						|
	}
 | 
						|
 | 
						|
	b := new(bytes.Buffer)
 | 
						|
	err := json.NewEncoder(b).Encode(&msg)
 | 
						|
 | 
						|
	return b.Bytes(), err
 | 
						|
}
 | 
						|
 | 
						|
func Init(version string) {
 | 
						|
	nixeryContext.Version = version
 | 
						|
	log.SetReportCaller(true)
 | 
						|
	log.SetFormatter(stackdriverFormatter{})
 | 
						|
}
 |