1// Copyright 2015 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// +build windows
15
16package log
17
18import (
19	"fmt"
20	"os"
21
22	"golang.org/x/sys/windows/svc/eventlog"
23
24	"github.com/sirupsen/logrus"
25)
26
27func init() {
28	setEventlogFormatter = func(l logger, name string, debugAsInfo bool) error {
29		if name == "" {
30			return fmt.Errorf("missing name parameter")
31		}
32
33		fmter, err := newEventlogger(name, debugAsInfo, l.entry.Logger.Formatter)
34		if err != nil {
35			fmt.Fprintf(os.Stderr, "error creating eventlog formatter: %v\n", err)
36			l.Errorf("can't connect logger to eventlog: %v", err)
37			return err
38		}
39		l.entry.Logger.Formatter = fmter
40		return nil
41	}
42}
43
44type eventlogger struct {
45	log         *eventlog.Log
46	debugAsInfo bool
47	wrap        logrus.Formatter
48}
49
50func newEventlogger(name string, debugAsInfo bool, fmter logrus.Formatter) (*eventlogger, error) {
51	logHandle, err := eventlog.Open(name)
52	if err != nil {
53		return nil, err
54	}
55	return &eventlogger{log: logHandle, debugAsInfo: debugAsInfo, wrap: fmter}, nil
56}
57
58func (s *eventlogger) Format(e *logrus.Entry) ([]byte, error) {
59	data, err := s.wrap.Format(e)
60	if err != nil {
61		fmt.Fprintf(os.Stderr, "eventlogger: can't format entry: %v\n", err)
62		return data, err
63	}
64
65	switch e.Level {
66	case logrus.PanicLevel:
67		fallthrough
68	case logrus.FatalLevel:
69		fallthrough
70	case logrus.ErrorLevel:
71		err = s.log.Error(102, e.Message)
72	case logrus.WarnLevel:
73		err = s.log.Warning(101, e.Message)
74	case logrus.InfoLevel:
75		err = s.log.Info(100, e.Message)
76	case logrus.DebugLevel:
77		if s.debugAsInfo {
78			err = s.log.Info(100, e.Message)
79		}
80	default:
81		err = s.log.Info(100, e.Message)
82	}
83
84	if err != nil {
85		fmt.Fprintf(os.Stderr, "eventlogger: can't send log to eventlog: %v\n", err)
86	}
87
88	return data, err
89}
90