summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go')
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go142
1 files changed, 142 insertions, 0 deletions
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go b/vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go
new file mode 100644
index 00000000..8766a964
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/mlog/syslog.go
@@ -0,0 +1,142 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package mlog
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io/ioutil"
+
+ "github.com/mattermost/logr"
+ "github.com/wiggin77/merror"
+ syslog "github.com/wiggin77/srslog"
+)
+
+// Syslog outputs log records to local or remote syslog.
+type Syslog struct {
+ logr.Basic
+ w *syslog.Writer
+}
+
+// SyslogParams provides parameters for dialing a syslog daemon.
+type SyslogParams struct {
+ IP string `json:"IP"`
+ Port int `json:"Port"`
+ Tag string `json:"Tag"`
+ TLS bool `json:"TLS"`
+ Cert string `json:"Cert"`
+ Insecure bool `json:"Insecure"`
+}
+
+// NewSyslogTarget creates a target capable of outputting log records to remote or local syslog, with or without TLS.
+func NewSyslogTarget(filter logr.Filter, formatter logr.Formatter, params *SyslogParams, maxQueue int) (*Syslog, error) {
+ network := "tcp"
+ var config *tls.Config
+
+ if params.TLS {
+ network = "tcp+tls"
+ config = &tls.Config{InsecureSkipVerify: params.Insecure}
+ if params.Cert != "" {
+ pool, err := getCertPool(params.Cert)
+ if err != nil {
+ return nil, err
+ }
+ config.RootCAs = pool
+ }
+ }
+ raddr := fmt.Sprintf("%s:%d", params.IP, params.Port)
+
+ writer, err := syslog.DialWithTLSConfig(network, raddr, syslog.LOG_INFO, params.Tag, config)
+ if err != nil {
+ return nil, err
+ }
+
+ s := &Syslog{w: writer}
+ s.Basic.Start(s, s, filter, formatter, maxQueue)
+
+ return s, nil
+}
+
+// Shutdown stops processing log records after making best effort to flush queue.
+func (s *Syslog) Shutdown(ctx context.Context) error {
+ errs := merror.New()
+
+ err := s.Basic.Shutdown(ctx)
+ errs.Append(err)
+
+ err = s.w.Close()
+ errs.Append(err)
+
+ return errs.ErrorOrNil()
+}
+
+// getCertPool returns a x509.CertPool containing the cert(s)
+// from `cert`, which can be a path to a .pem or .crt file,
+// or a base64 encoded cert.
+func getCertPool(cert string) (*x509.CertPool, error) {
+ if cert == "" {
+ return nil, errors.New("no cert provided")
+ }
+
+ // first treat as a file and try to read.
+ serverCert, err := ioutil.ReadFile(cert)
+ if err != nil {
+ // maybe it's a base64 encoded cert
+ serverCert, err = base64.StdEncoding.DecodeString(cert)
+ if err != nil {
+ return nil, errors.New("cert cannot be read")
+ }
+ }
+
+ pool := x509.NewCertPool()
+ if ok := pool.AppendCertsFromPEM(serverCert); ok {
+ return pool, nil
+ }
+ return nil, errors.New("cannot parse cert")
+}
+
+// Write converts the log record to bytes, via the Formatter,
+// and outputs to syslog.
+func (s *Syslog) Write(rec *logr.LogRec) error {
+ _, stacktrace := s.IsLevelEnabled(rec.Level())
+
+ buf := rec.Logger().Logr().BorrowBuffer()
+ defer rec.Logger().Logr().ReleaseBuffer(buf)
+
+ buf, err := s.Formatter().Format(rec, stacktrace, buf)
+ if err != nil {
+ return err
+ }
+ txt := buf.String()
+
+ switch rec.Level() {
+ case logr.Panic, logr.Fatal:
+ err = s.w.Crit(txt)
+ case logr.Error:
+ err = s.w.Err(txt)
+ case logr.Warn:
+ err = s.w.Warning(txt)
+ case logr.Debug, logr.Trace:
+ err = s.w.Debug(txt)
+ default:
+ // logr.Info plus all custom levels.
+ err = s.w.Info(txt)
+ }
+
+ if err != nil {
+ reporter := rec.Logger().Logr().ReportError
+ reporter(fmt.Errorf("syslog write fail: %w", err))
+ // syslog writer will try to reconnect.
+ }
+ return err
+}
+
+// String returns a string representation of this target.
+func (s *Syslog) String() string {
+ return "SyslogTarget"
+}