Skip to content

Commit 87e98f0

Browse files
committed
feat(logging): updated syslog writer to work with log15 log interface, closes grafana#4590
1 parent 93fdc18 commit 87e98f0

File tree

3 files changed

+102
-104
lines changed

3 files changed

+102
-104
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
* **Theme**: Add default theme to config file [#5011](https://github.com/grafana/grafana/pull/5011)
99
* **Page Footer**: Added page footer with links to docs, shows Grafana version and info if new version is available, closes [#4889](https://github.com/grafana/grafana/pull/4889)
1010
* **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211)
11+
* **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590)
12+
13+
## Breaking changes
14+
* **Logging** : Changed default logging output format (now structured into message, and key value pairs, with logger key acting as component). You can also no change in config to json log ouput.
1115

1216
# 3.0.4 Patch release (2016-05-25)
1317
* **Panel**: Fixed blank dashboard issue when switching to other dashboard while in fullscreen edit mode, fixes [#5163](https://github.com/grafana/grafana/pull/5163)

pkg/log/log.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,15 +157,20 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) {
157157

158158
loggersToClose = append(loggersToClose, fileHandler)
159159
handler = fileHandler
160+
case "syslog":
161+
sysLogHandler := NewSyslog()
162+
sysLogHandler.Network = sec.Key("network").MustString("")
163+
sysLogHandler.Address = sec.Key("address").MustString("")
164+
sysLogHandler.Facility = sec.Key("facility").MustString("local7")
165+
sysLogHandler.Tag = sec.Key("tag").MustString("")
166+
167+
if err := sysLogHandler.Init(); err != nil {
168+
Root.Error("Failed to init syslog log handler", "error", err)
169+
os.Exit(1)
170+
}
160171

161-
// case "syslog":
162-
// LogConfigs[i] = util.DynMap{
163-
// "level": level,
164-
// "network": sec.Key("network").MustString(""),
165-
// "address": sec.Key("address").MustString(""),
166-
// "facility": sec.Key("facility").MustString("local7"),
167-
// "tag": sec.Key("tag").MustString(""),
168-
// }
172+
loggersToClose = append(loggersToClose, sysLogHandler)
173+
handler = sysLogHandler
169174
}
170175

171176
for key, value := range defaultFilters {
@@ -174,10 +179,6 @@ func ReadLoggingConfig(modes []string, logsPath string, cfg *ini.File) {
174179
}
175180
}
176181

177-
for key, value := range modeFilters {
178-
fmt.Printf("key: %v, value: %v \n", key, value)
179-
}
180-
181182
handler = LogFilterHandler(level, modeFilters, handler)
182183
handlers = append(handlers, handler)
183184
}

pkg/log/syslog.go

Lines changed: 85 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,95 +2,88 @@
22

33
package log
44

5-
//
6-
// import (
7-
// "encoding/json"
8-
// "errors"
9-
// "log/syslog"
10-
// )
11-
//
12-
// type SyslogWriter struct {
13-
// syslog *syslog.Writer
14-
// Network string `json:"network"`
15-
// Address string `json:"address"`
16-
// Facility string `json:"facility"`
17-
// Tag string `json:"tag"`
18-
// }
19-
//
20-
// func NewSyslog() LoggerInterface {
21-
// return new(SyslogWriter)
22-
// }
23-
//
24-
// func (sw *SyslogWriter) Init(config string) error {
25-
// if err := json.Unmarshal([]byte(config), sw); err != nil {
26-
// return err
27-
// }
28-
//
29-
// prio, err := parseFacility(sw.Facility)
30-
// if err != nil {
31-
// return err
32-
// }
33-
//
34-
// w, err := syslog.Dial(sw.Network, sw.Address, prio, sw.Tag)
35-
// if err != nil {
36-
// return err
37-
// }
38-
//
39-
// sw.syslog = w
40-
// return nil
41-
// }
42-
//
43-
// func (sw *SyslogWriter) WriteMsg(msg string, skip int, level LogLevel) error {
44-
// var err error
45-
//
46-
// switch level {
47-
// case TRACE, DEBUG:
48-
// err = sw.syslog.Debug(msg)
49-
// case INFO:
50-
// err = sw.syslog.Info(msg)
51-
// case WARN:
52-
// err = sw.syslog.Warning(msg)
53-
// case ERROR:
54-
// err = sw.syslog.Err(msg)
55-
// case CRITICAL:
56-
// err = sw.syslog.Crit(msg)
57-
// case FATAL:
58-
// err = sw.syslog.Alert(msg)
59-
// default:
60-
// err = errors.New("invalid syslog level")
61-
// }
62-
//
63-
// return err
64-
// }
65-
//
66-
// func (sw *SyslogWriter) Destroy() {
67-
// sw.syslog.Close()
68-
// }
69-
//
70-
// func (sw *SyslogWriter) Flush() {}
71-
//
72-
// var facilities = map[string]syslog.Priority{
73-
// "user": syslog.LOG_USER,
74-
// "daemon": syslog.LOG_DAEMON,
75-
// "local0": syslog.LOG_LOCAL0,
76-
// "local1": syslog.LOG_LOCAL1,
77-
// "local2": syslog.LOG_LOCAL2,
78-
// "local3": syslog.LOG_LOCAL3,
79-
// "local4": syslog.LOG_LOCAL4,
80-
// "local5": syslog.LOG_LOCAL5,
81-
// "local6": syslog.LOG_LOCAL6,
82-
// "local7": syslog.LOG_LOCAL7,
83-
// }
84-
//
85-
// func parseFacility(facility string) (syslog.Priority, error) {
86-
// prio, ok := facilities[facility]
87-
// if !ok {
88-
// return syslog.LOG_LOCAL0, errors.New("invalid syslog facility")
89-
// }
90-
//
91-
// return prio, nil
92-
// }
93-
//
94-
// func init() {
95-
// Register("syslog", NewSyslog)
96-
// }
5+
import (
6+
"errors"
7+
"log/syslog"
8+
9+
"github.com/inconshreveable/log15"
10+
)
11+
12+
type SysLogHandler struct {
13+
syslog *syslog.Writer
14+
Network string
15+
Address string
16+
Facility string
17+
Tag string
18+
Format log15.Format
19+
}
20+
21+
func NewSyslog() *SysLogHandler {
22+
return &SysLogHandler{
23+
Format: log15.LogfmtFormat(),
24+
}
25+
}
26+
27+
func (sw *SysLogHandler) Init() error {
28+
prio, err := parseFacility(sw.Facility)
29+
if err != nil {
30+
return err
31+
}
32+
33+
w, err := syslog.Dial(sw.Network, sw.Address, prio, sw.Tag)
34+
if err != nil {
35+
return err
36+
}
37+
38+
sw.syslog = w
39+
return nil
40+
}
41+
42+
func (sw *SysLogHandler) Log(r *log15.Record) error {
43+
var err error
44+
45+
msg := string(sw.Format.Format(r))
46+
47+
switch r.Lvl {
48+
case log15.LvlDebug:
49+
err = sw.syslog.Debug(msg)
50+
case log15.LvlInfo:
51+
err = sw.syslog.Info(msg)
52+
case log15.LvlWarn:
53+
err = sw.syslog.Warning(msg)
54+
case log15.LvlError:
55+
err = sw.syslog.Err(msg)
56+
case log15.LvlCrit:
57+
err = sw.syslog.Crit(msg)
58+
default:
59+
err = errors.New("invalid syslog level")
60+
}
61+
62+
return err
63+
}
64+
65+
func (sw *SysLogHandler) Close() {
66+
sw.syslog.Close()
67+
}
68+
69+
var facilities = map[string]syslog.Priority{
70+
"user": syslog.LOG_USER,
71+
"daemon": syslog.LOG_DAEMON,
72+
"local0": syslog.LOG_LOCAL0,
73+
"local1": syslog.LOG_LOCAL1,
74+
"local2": syslog.LOG_LOCAL2,
75+
"local3": syslog.LOG_LOCAL3,
76+
"local4": syslog.LOG_LOCAL4,
77+
"local5": syslog.LOG_LOCAL5,
78+
"local6": syslog.LOG_LOCAL6,
79+
"local7": syslog.LOG_LOCAL7,
80+
}
81+
82+
func parseFacility(facility string) (syslog.Priority, error) {
83+
prio, ok := facilities[facility]
84+
if !ok {
85+
return syslog.LOG_LOCAL0, errors.New("invalid syslog facility")
86+
}
87+
88+
return prio, nil
89+
}

0 commit comments

Comments
 (0)