github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/send/formatter.go (about)

     1  package send
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"path/filepath"
     7  	"runtime"
     8  
     9  	"github.com/mongodb/grip/message"
    10  )
    11  
    12  const (
    13  	defaultFormatTmpl  = "[p=%s]: %s"
    14  	callSiteTmpl       = "[p=%s] [%s:%d]: %s"
    15  	completeFormatTmpl = "[%s] (p=%s) %s"
    16  )
    17  
    18  // MessageFormatter is a function type used by senders to construct the
    19  // entire string returned as part of the output. This makes it
    20  // possible to modify the logging format without needing to implement
    21  // new Sender interfaces.
    22  type MessageFormatter func(message.Composer) (string, error)
    23  
    24  // MakeJSONFormatter returns a MessageFormatter, that returns messages
    25  // as the string form of a JSON document built using the Raw method of
    26  // the Composer. Returns an error if there was a problem marshalling JSON.
    27  func MakeJSONFormatter() MessageFormatter {
    28  	return func(m message.Composer) (string, error) {
    29  		out, err := json.Marshal(m.Raw())
    30  		if err != nil {
    31  			return "", err
    32  		}
    33  
    34  		return string(out), nil
    35  	}
    36  }
    37  
    38  // MakeDefaultFormatter returns a MessageFormatter that will produce a
    39  // message in the following format:
    40  //
    41  //	[p=<level>]: <message>
    42  //
    43  // It can never error.
    44  func MakeDefaultFormatter() MessageFormatter {
    45  	return func(m message.Composer) (string, error) {
    46  		return fmt.Sprintf(defaultFormatTmpl, m.Priority(), m.String()), nil
    47  	}
    48  }
    49  
    50  // MakePlainFormatter returns a MessageFormatter that simply returns the
    51  // string format of the log message.
    52  func MakePlainFormatter() MessageFormatter {
    53  	return func(m message.Composer) (string, error) {
    54  		return m.String(), nil
    55  	}
    56  }
    57  
    58  // MakeCallSiteFormatter returns a MessageFormater that formats
    59  // messages with the following format:
    60  //
    61  //	[p=<levvel>] [<fileName>:<lineNumber>]: <message>
    62  //
    63  // It can never error.
    64  func MakeCallSiteFormatter(depth int) MessageFormatter {
    65  	depth++
    66  	return func(m message.Composer) (string, error) {
    67  		file, line := callerInfo(depth)
    68  		return fmt.Sprintf(callSiteTmpl, m.Priority(), file, line, m), nil
    69  	}
    70  }
    71  
    72  // MakeXMPPFormatter returns a MessageFormatter that will produce
    73  // messages in the following format, used primarily by the xmpp logger:
    74  //
    75  //	[<name>] (p=<priority>) <message>
    76  //
    77  // It can never error.
    78  func MakeXMPPFormatter(name string) MessageFormatter {
    79  	return func(m message.Composer) (string, error) {
    80  		return fmt.Sprintf(completeFormatTmpl, name, m.Priority(), m.String()), nil
    81  	}
    82  }
    83  
    84  func callerInfo(depth int) (string, int) {
    85  	// increase depth to account for callerInfo itself.
    86  	depth++
    87  
    88  	// get caller info.
    89  	_, file, line, _ := runtime.Caller(depth)
    90  
    91  	// get the directory and filename
    92  	dir, fileName := filepath.Split(file)
    93  	file = filepath.Join(filepath.Base(dir), fileName)
    94  
    95  	return file, line
    96  }