aboutsummaryrefslogtreecommitdiffstats
path: root/log/handler_stackdriver.go
blob: 68e8b32b2b9b770cf0ac26b9d8490b00f87c8796 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package log

import (
    "encoding/json"
    "fmt"

    "cloud.google.com/go/logging"
    "golang.org/x/net/context"
)

// LabelMap defines stackdriver labels struct.
type LabelMap map[string]string

// LogMsg defines json object of log message.
type LogMsg struct {
    Msg   string   `json:"msg"`
    Label LabelMap `json:"label"`
}

// StackdriverHandler is a log handler of stackdrvier.
type StackdriverHandler struct {
    client *logging.Client
    logger *logging.Logger
}

// NewStackDriverHandler returns a new handler.
func NewStackDriverHandler(projectID, logName string) (*StackdriverHandler, error) {
    client, err := logging.NewClient(context.Background(), projectID)
    if err != nil {
        return nil, fmt.Errorf("Failed to create client: %v", err)
    }
    return &StackdriverHandler{
        client:    client,
        logger:    client.Logger(logName),
        OmitEmpty: true,
    }, nil
}

// Log send to stackdriver.
func (h *StackdriverHandler) Log(r *Record) error {
    e := logging.Entry{
        Payload:   r.Msg,
        Timestamp: r.Time,
        Severity:  asSeverity(r.Lvl),
    }
    e.Labels = LabelMap{"tag": "test"}
    parseLabel(&e)
    h.logger.Log(e)
}

func parseLabel(e *logging.Entry) {
    var log LogMsg
    payload := []byte(e.Payload.(string))
    err := json.Unmarshal(payload, &log)
    if err != nil {
        fmt.Println("%v", err)
        return
    }

    e.Payload = log.Msg
    e.Labels = log.Label
}

func asSeverity(l Lvl) logging.Severity {
    switch l {
    case LvlDebug:
        return logging.Debug
    case LvlCrit:
        return logging.Emergency
    case LvlError:
        return logging.Error
    case LvlInfo:
        return logging.Info
    case LvlWarn:
        return logging.Warning
    default:
        return logging.Notice
    }
}

// Close is delegated to the client (if any)
func (h *StackdriverHandler) Close() error {
    if h.client == nil {
        return nil
    }
    return h.client.Close()
}