mirror of
https://github.com/mjl-/mox.git
synced 2025-07-10 10:34:40 +03:00
switch to slog.Logger for logging, for easier reuse of packages by external software
we don't want external software to include internal details like mlog. slog.Logger is/will be the standard. we still have mlog for its helper functions, and its handler that logs in concise logfmt used by mox. packages that are not meant for reuse still pass around mlog.Log for convenience. we use golang.org/x/exp/slog because we also support the previous Go toolchain version. with the next Go release, we'll switch to the builtin slog.
This commit is contained in:
@ -23,6 +23,7 @@ import (
|
||||
_ "embed"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slog"
|
||||
|
||||
"github.com/mjl-/bstore"
|
||||
"github.com/mjl-/sherpa"
|
||||
@ -33,7 +34,6 @@ import (
|
||||
"github.com/mjl-/mox/dns"
|
||||
"github.com/mjl-/mox/message"
|
||||
"github.com/mjl-/mox/metrics"
|
||||
"github.com/mjl-/mox/mlog"
|
||||
"github.com/mjl-/mox/mox-"
|
||||
"github.com/mjl-/mox/moxio"
|
||||
"github.com/mjl-/mox/moxvar"
|
||||
@ -55,7 +55,7 @@ type Webmail struct {
|
||||
func mustParseAPI(api string, buf []byte) (doc sherpadoc.Section) {
|
||||
err := json.Unmarshal(buf, &doc)
|
||||
if err != nil {
|
||||
xlog.Fatalx("parsing webmail api docs", err, mlog.Field("api", api))
|
||||
pkglog.Fatalx("parsing webmail api docs", err, slog.String("api", api))
|
||||
}
|
||||
return doc
|
||||
}
|
||||
@ -71,14 +71,14 @@ func makeSherpaHandler(maxMessageSize int64) (http.Handler, error) {
|
||||
func init() {
|
||||
collector, err := sherpaprom.NewCollector("moxwebmail", nil)
|
||||
if err != nil {
|
||||
xlog.Fatalx("creating sherpa prometheus collector", err)
|
||||
pkglog.Fatalx("creating sherpa prometheus collector", err)
|
||||
}
|
||||
|
||||
sherpaHandlerOpts = &sherpa.HandlerOpts{Collector: collector, AdjustFunctionNames: "none"}
|
||||
// Just to validate.
|
||||
_, err = makeSherpaHandler(0)
|
||||
if err != nil {
|
||||
xlog.Fatalx("sherpa handler", err)
|
||||
pkglog.Fatalx("sherpa handler", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,9 +112,9 @@ func (Webmail) Request(ctx context.Context, req Request) {
|
||||
// ParsedMessage returns enough to render the textual body of a message. It is
|
||||
// assumed the client already has other fields through MessageItem.
|
||||
func (Webmail) ParsedMessage(ctx context.Context, msgID int64) (pm ParsedMessage) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -234,8 +234,8 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||
// todo: consider making this an HTTP POST, so we can upload as regular form, which is probably more efficient for encoding for the client and we can stream the data in.
|
||||
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
log := xlog.WithContext(ctx).Fields(mlog.Field("account", reqInfo.AccountName))
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
log := pkglog.WithContext(ctx).With(slog.String("account", reqInfo.AccountName))
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -326,7 +326,7 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||
}
|
||||
|
||||
// Create file to compose message into.
|
||||
dataFile, err := store.CreateMessageTemp("webmail-submit")
|
||||
dataFile, err := store.CreateMessageTemp(log, "webmail-submit")
|
||||
xcheckf(ctx, err, "creating temporary file for message")
|
||||
defer store.CloseRemoveTempFile(log, dataFile, "message to submit")
|
||||
|
||||
@ -361,7 +361,7 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||
// Note: we don't have "via" or "with", there is no registered for webmail.
|
||||
recvHdr.Add(" ", "Received:", "from", recvFrom, "by", recvBy, "id", recvID) // ../rfc/5321:3158
|
||||
if reqInfo.Request.TLS != nil {
|
||||
recvHdr.Add(" ", message.TLSReceivedComment(log, *reqInfo.Request.TLS)...)
|
||||
recvHdr.Add(" ", mox.TLSReceivedComment(log, *reqInfo.Request.TLS)...)
|
||||
}
|
||||
recvHdr.Add(" ", "for", "<"+rcptTo+">;", time.Now().Format(message.RFC5322Z))
|
||||
return recvHdr.String()
|
||||
@ -558,7 +558,7 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||
fd := fromAddr.Address.Domain
|
||||
confDom, _ := mox.Conf.Domain(fd)
|
||||
if len(confDom.DKIM.Sign) > 0 {
|
||||
dkimHeaders, err := dkim.Sign(ctx, fromAddr.Address.Localpart, fd, confDom.DKIM, smtputf8, dataFile)
|
||||
dkimHeaders, err := dkim.Sign(ctx, log.Logger, fromAddr.Address.Localpart, fd, confDom.DKIM, smtputf8, dataFile)
|
||||
if err != nil {
|
||||
metricServerErrors.WithLabelValues("dkimsign").Inc()
|
||||
}
|
||||
@ -671,9 +671,9 @@ func (w Webmail) MessageSubmit(ctx context.Context, m SubmitMessage) {
|
||||
// MessageMove moves messages to another mailbox. If the message is already in
|
||||
// the mailbox an error is returned.
|
||||
func (Webmail) MessageMove(ctx context.Context, messageIDs []int64, mailboxID int64) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -802,9 +802,9 @@ func (Webmail) MessageMove(ctx context.Context, messageIDs []int64, mailboxID in
|
||||
|
||||
// MessageDelete permanently deletes messages, without moving them to the Trash mailbox.
|
||||
func (Webmail) MessageDelete(ctx context.Context, messageIDs []int64) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -895,9 +895,9 @@ func (Webmail) MessageDelete(ctx context.Context, messageIDs []int64) {
|
||||
// FlagsAdd adds flags, either system flags like \Seen or custom keywords. The
|
||||
// flags should be lower-case, but will be converted and verified.
|
||||
func (Webmail) FlagsAdd(ctx context.Context, messageIDs []int64, flaglist []string) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -978,9 +978,9 @@ func (Webmail) FlagsAdd(ctx context.Context, messageIDs []int64, flaglist []stri
|
||||
|
||||
// FlagsClear clears flags, either system flags like \Seen or custom keywords.
|
||||
func (Webmail) FlagsClear(ctx context.Context, messageIDs []int64, flaglist []string) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1056,9 +1056,9 @@ func (Webmail) FlagsClear(ctx context.Context, messageIDs []int64, flaglist []st
|
||||
|
||||
// MailboxCreate creates a new mailbox.
|
||||
func (Webmail) MailboxCreate(ctx context.Context, name string) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1086,9 +1086,9 @@ func (Webmail) MailboxCreate(ctx context.Context, name string) {
|
||||
|
||||
// MailboxDelete deletes a mailbox and all its messages.
|
||||
func (Webmail) MailboxDelete(ctx context.Context, mailboxID int64) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1123,16 +1123,16 @@ func (Webmail) MailboxDelete(ctx context.Context, mailboxID int64) {
|
||||
for _, mID := range removeMessageIDs {
|
||||
p := acc.MessagePath(mID)
|
||||
err := os.Remove(p)
|
||||
log.Check(err, "removing message file for mailbox delete", mlog.Field("path", p))
|
||||
log.Check(err, "removing message file for mailbox delete", slog.String("path", p))
|
||||
}
|
||||
}
|
||||
|
||||
// MailboxEmpty empties a mailbox, removing all messages from the mailbox, but not
|
||||
// its child mailboxes.
|
||||
func (Webmail) MailboxEmpty(ctx context.Context, mailboxID int64) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1196,16 +1196,16 @@ func (Webmail) MailboxEmpty(ctx context.Context, mailboxID int64) {
|
||||
for _, m := range expunged {
|
||||
p := acc.MessagePath(m.ID)
|
||||
err := os.Remove(p)
|
||||
log.Check(err, "removing message file after emptying mailbox", mlog.Field("path", p))
|
||||
log.Check(err, "removing message file after emptying mailbox", slog.String("path", p))
|
||||
}
|
||||
}
|
||||
|
||||
// MailboxRename renames a mailbox, possibly moving it to a new parent. The mailbox
|
||||
// ID and its messages are unchanged.
|
||||
func (Webmail) MailboxRename(ctx context.Context, mailboxID int64, newName string) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1239,9 +1239,9 @@ func (Webmail) MailboxRename(ctx context.Context, mailboxID int64, newName strin
|
||||
// matches, most recently used first, and whether this is the full list and further
|
||||
// requests for longer prefixes aren't necessary.
|
||||
func (Webmail) CompleteRecipient(ctx context.Context, search string) ([]string, bool) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1342,9 +1342,9 @@ func addressString(a message.Address, smtputf8 bool) string {
|
||||
|
||||
// MailboxSetSpecialUse sets the special use flags of a mailbox.
|
||||
func (Webmail) MailboxSetSpecialUse(ctx context.Context, mb store.Mailbox) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1395,9 +1395,9 @@ func (Webmail) MailboxSetSpecialUse(ctx context.Context, mb store.Mailbox) {
|
||||
// children. The messageIDs are typically thread roots. But not all roots
|
||||
// (without parent) of a thread need to have the same collapsed state.
|
||||
func (Webmail) ThreadCollapse(ctx context.Context, messageIDs []int64, collapse bool) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1455,9 +1455,9 @@ func (Webmail) ThreadCollapse(ctx context.Context, messageIDs []int64, collapse
|
||||
// ThreadMute saves the ThreadMute field for the messages and their children.
|
||||
// If messages are muted, they are also marked collapsed.
|
||||
func (Webmail) ThreadMute(ctx context.Context, messageIDs []int64, mute bool) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
err := acc.Close()
|
||||
@ -1555,7 +1555,7 @@ type RecipientSecurity struct {
|
||||
// RecipientSecurity looks up security properties of the address in the
|
||||
// single-address message addressee (as it appears in a To/Cc/Bcc/etc header).
|
||||
func (Webmail) RecipientSecurity(ctx context.Context, messageAddressee string) (RecipientSecurity, error) {
|
||||
resolver := dns.StrictResolver{Pkg: "webmail"}
|
||||
resolver := dns.StrictResolver{Pkg: "webmail", Log: pkglog.WithContext(ctx).Logger}
|
||||
return recipientSecurity(ctx, resolver, messageAddressee)
|
||||
}
|
||||
|
||||
@ -1565,15 +1565,15 @@ func logPanic(ctx context.Context) {
|
||||
if x == nil {
|
||||
return
|
||||
}
|
||||
log := xlog.WithContext(ctx)
|
||||
log.Error("recover from panic", mlog.Field("panic", x))
|
||||
log := pkglog.WithContext(ctx)
|
||||
log.Error("recover from panic", slog.Any("panic", x))
|
||||
debug.PrintStack()
|
||||
metrics.PanicInc(metrics.Webmail)
|
||||
}
|
||||
|
||||
// separate function for testing with mocked resolver.
|
||||
func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddressee string) (RecipientSecurity, error) {
|
||||
log := xlog.WithContext(ctx)
|
||||
log := pkglog.WithContext(ctx)
|
||||
|
||||
rs := RecipientSecurity{
|
||||
SecurityResultUnknown,
|
||||
@ -1601,7 +1601,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
defer logPanic(ctx)
|
||||
defer wg.Done()
|
||||
|
||||
policy, _, _, err := mtastsdb.Get(ctx, resolver, addr.Domain)
|
||||
policy, _, _, err := mtastsdb.Get(ctx, log.Logger, resolver, addr.Domain)
|
||||
if policy != nil && policy.Mode == mtasts.ModeEnforce {
|
||||
rs.MTASTS = SecurityResultYes
|
||||
} else if err == nil {
|
||||
@ -1617,7 +1617,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
defer logPanic(ctx)
|
||||
defer wg.Done()
|
||||
|
||||
_, origNextHopAuthentic, expandedNextHopAuthentic, _, hosts, _, err := smtpclient.GatherDestinations(ctx, log, resolver, dns.IPDomain{Domain: addr.Domain})
|
||||
_, origNextHopAuthentic, expandedNextHopAuthentic, _, hosts, _, err := smtpclient.GatherDestinations(ctx, log.Logger, resolver, dns.IPDomain{Domain: addr.Domain})
|
||||
if err != nil {
|
||||
rs.DNSSEC = SecurityResultError
|
||||
return
|
||||
@ -1641,7 +1641,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
|
||||
// Resolve the IPs. Required for DANE to prevent bad DNS servers from causing an
|
||||
// error result instead of no-DANE result.
|
||||
authentic, expandedAuthentic, expandedHost, _, _, err := smtpclient.GatherIPs(ctx, log, resolver, host, map[string][]net.IP{})
|
||||
authentic, expandedAuthentic, expandedHost, _, _, err := smtpclient.GatherIPs(ctx, log.Logger, resolver, host, map[string][]net.IP{})
|
||||
if err != nil {
|
||||
rs.DANE = SecurityResultError
|
||||
return
|
||||
@ -1651,7 +1651,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
return
|
||||
}
|
||||
|
||||
daneRequired, _, _, err := smtpclient.GatherTLSA(ctx, log, resolver, host.Domain, expandedAuthentic, expandedHost)
|
||||
daneRequired, _, _, err := smtpclient.GatherTLSA(ctx, log.Logger, resolver, host.Domain, expandedAuthentic, expandedHost)
|
||||
if err != nil {
|
||||
rs.DANE = SecurityResultError
|
||||
return
|
||||
@ -1664,7 +1664,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
|
||||
// STARTTLS and RequireTLS
|
||||
reqInfo := ctx.Value(requestInfoCtxKey).(requestInfo)
|
||||
acc, err := store.OpenAccount(reqInfo.AccountName)
|
||||
acc, err := store.OpenAccount(log, reqInfo.AccountName)
|
||||
xcheckf(ctx, err, "open account")
|
||||
defer func() {
|
||||
if acc != nil {
|
||||
@ -1682,7 +1682,7 @@ func recipientSecurity(ctx context.Context, resolver dns.Resolver, messageAddres
|
||||
} else if err != nil {
|
||||
rs.STARTTLS = SecurityResultError
|
||||
rs.RequireTLS = SecurityResultError
|
||||
log.Errorx("looking up recipient domain", err, mlog.Field("domain", addr.Domain))
|
||||
log.Errorx("looking up recipient domain", err, slog.Any("domain", addr.Domain))
|
||||
return nil
|
||||
}
|
||||
if rd.STARTTLS {
|
||||
|
Reference in New Issue
Block a user