main

mattermost/focalboard

Last updated at: 29/12/2023 09:39

logtarget.go

TLDR

This file provides a log target implementation for the Mattermost plugin API. It creates a plugin log adapter and writes log messages to the plugin API.

Classes

pluginTargetFactory

This class is responsible for creating a plugin log adapter when a custom target type appears in the logging configuration. It has a method createTarget() that takes a target type and options as parameters and returns a log target implementation.

pluginLogAdapter

This class is a simple log target that writes log messages to the plugin API. It has methods Init(), Shutdown(), and Write() for log initialization, shutdown, and writing log messages, respectively.

END

package main

import (
	"bytes"
	"encoding/json"
	"fmt"

	pluginapi "github.com/mattermost/mattermost-plugin-api"

	"github.com/mattermost/mattermost-server/v6/shared/mlog"
)

const (
	pluginTargetType = "focalboard_plugin_adapter"
)

// pluginTargetFactory creates a plugin log adapter when a custom target type appears in
// the logging configuration.
type pluginTargetFactory struct {
	logService *pluginapi.LogService
}

func newPluginTargetFactory(logService *pluginapi.LogService) pluginTargetFactory {
	return pluginTargetFactory{
		logService: logService,
	}
}

func (ptf pluginTargetFactory) createTarget(targetType string, options json.RawMessage) (mlog.Target, error) {
	if targetType != pluginTargetType {
		return nil, ErrInvalidTargetType{targetType}
	}
	return newPluginAdapterTarget(ptf.logService), nil
}

// pluginLogAdapter is a simple log target that writes to the plugin API.
type pluginLogAdapter struct {
	logService *pluginapi.LogService
}

func newPluginAdapterTarget(logService *pluginapi.LogService) mlog.Target {
	return &pluginLogAdapter{
		logService: logService,
	}
}

func (pla *pluginLogAdapter) Init() error {
	return nil
}

func (pla *pluginLogAdapter) Shutdown() error {
	return nil
}

func (pla *pluginLogAdapter) Write(p []byte, rec *mlog.LogRec) (int, error) {
	fields := rec.Fields()

	args := make([]interface{}, 0, len(fields)*2)
	buf := &bytes.Buffer{}
	var err error
	for _, fld := range fields {
		err = fld.ValueString(buf, mlog.ShouldQuote)
		if err != nil {
			return 0, err
		}
		args = append(args, fld.Key, buf.String())
		buf.Reset()
	}

	switch rec.Level() {
	case mlog.LvlDebug:
		pla.logService.Debug(rec.Msg(), args...)
	case mlog.LvlError:
		pla.logService.Error(rec.Msg(), args...)
	case mlog.LvlInfo:
		pla.logService.Info(rec.Msg(), args...)
	case mlog.LvlWarn:
		pla.logService.Warn(rec.Msg(), args...)
	case mlog.LvlCritical, mlog.LvlFatal:
		args = append(args, mlog.String("level", rec.Level().Name))
		pla.logService.Error(rec.Msg(), args...)
	default:
		args = append(args, mlog.String("level", rec.Level().Name))
		pla.logService.Info(rec.Msg(), args...)
	}
	return 0, nil
}

// ErrInvalidTargetType is returned when a log config factory does not recognize the
// target type.
type ErrInvalidTargetType struct {
	name string
}

func (e ErrInvalidTargetType) Error() string {
	return fmt.Sprintf("invalid log target type '%s'", e.name)
}