Browse Source

Merge pull request #3161 from mischief/syslog

syslog support closes #3160
Carl Bergquist 10 years ago
parent
commit
225e7a6a32
3 changed files with 113 additions and 0 deletions
  1. 12 0
      conf/defaults.ini
  2. 93 0
      pkg/log/syslog.go
  3. 8 0
      pkg/setting/setting.go

+ 12 - 0
conf/defaults.ini

@@ -245,6 +245,18 @@ daily_rotate = true
 # Expired days of log file(delete after max days), default is 7
 max_days = 7
 
+[log.syslog]
+level =
+# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
+network =
+address =
+
+# Syslog facility. user, daemon and local0 through local7 are valid.
+facility =
+
+# Syslog tag. By default, the process' argv[0] is used.
+tag =
+
 #################################### AMPQ Event Publisher ##########################
 [event_publisher]
 enabled = false

+ 93 - 0
pkg/log/syslog.go

@@ -0,0 +1,93 @@
+package log
+
+import (
+	"encoding/json"
+	"errors"
+	"log/syslog"
+)
+
+type SyslogWriter struct {
+	syslog   *syslog.Writer
+	Network  string `json:"network"`
+	Address  string `json:"address"`
+	Facility string `json:"facility"`
+	Tag      string `json:"tag"`
+}
+
+func NewSyslog() LoggerInterface {
+	return new(SyslogWriter)
+}
+
+func (sw *SyslogWriter) Init(config string) error {
+	if err := json.Unmarshal([]byte(config), sw); err != nil {
+		return err
+	}
+
+	prio, err := parseFacility(sw.Facility)
+	if err != nil {
+		return err
+	}
+
+	w, err := syslog.Dial(sw.Network, sw.Address, prio, sw.Tag)
+	if err != nil {
+		return err
+	}
+
+	sw.syslog = w
+	return nil
+}
+
+func (sw *SyslogWriter) WriteMsg(msg string, skip, level int) error {
+	var err error
+
+	switch level {
+	case TRACE, DEBUG:
+		err = sw.syslog.Debug(msg)
+	case INFO:
+		err = sw.syslog.Info(msg)
+	case WARN:
+		err = sw.syslog.Warning(msg)
+	case ERROR:
+		err = sw.syslog.Err(msg)
+	case CRITICAL:
+		err = sw.syslog.Crit(msg)
+	case FATAL:
+		err = sw.syslog.Alert(msg)
+	default:
+		err = errors.New("invalid syslog level")
+	}
+
+	return err
+}
+
+func (sw *SyslogWriter) Destroy() {
+	sw.syslog.Close()
+}
+
+func (sw *SyslogWriter) Flush() {}
+
+var facilities = map[string]syslog.Priority{
+	"user":   syslog.LOG_USER,
+	"daemon": syslog.LOG_DAEMON,
+	"local0": syslog.LOG_LOCAL0,
+	"local1": syslog.LOG_LOCAL1,
+	"local2": syslog.LOG_LOCAL2,
+	"local3": syslog.LOG_LOCAL3,
+	"local4": syslog.LOG_LOCAL4,
+	"local5": syslog.LOG_LOCAL5,
+	"local6": syslog.LOG_LOCAL6,
+	"local7": syslog.LOG_LOCAL7,
+}
+
+func parseFacility(facility string) (syslog.Priority, error) {
+	prio, ok := facilities[facility]
+	if !ok {
+		return syslog.LOG_LOCAL0, errors.New("invalid syslog facility")
+	}
+
+	return prio, nil
+}
+
+func init() {
+	Register("syslog", NewSyslog)
+}

+ 8 - 0
pkg/setting/setting.go

@@ -573,6 +573,14 @@ func initLogging(args *CommandLineArgs) {
 				"driver": sec.Key("driver").String(),
 				"conn":   sec.Key("conn").String(),
 			}
+		case "syslog":
+			LogConfigs[i] = util.DynMap{
+				"level":    level,
+				"network":  sec.Key("network").MustString(""),
+				"address":  sec.Key("address").MustString(""),
+				"facility": sec.Key("facility").MustString("local7"),
+				"tag":      sec.Key("tag").MustString(""),
+			}
 		}
 
 		cfgJsonBytes, _ := json.Marshal(LogConfigs[i])