aboutsummaryrefslogtreecommitdiffstats
path: root/logger/glog/glog_file.go
blob: 847e9b07c8233911ee2d9b14bdbda12159012c4d (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
//
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// File I/O for logs.

package glog

import (
    "errors"
    "fmt"
    "os"
    "os/user"
    "path/filepath"
    "strings"
    "sync"
    "time"
)

// MaxSize is the maximum size of a log file in bytes.
var MaxSize uint64 = 1024 * 1024 * 1800

// logDirs lists the candidate directories for new log files.
var logDirs []string

// If non-empty, overrides the choice of directory in which to write logs.
// See createLogDirs for the full list of possible destinations.
//var logDir = flag.String("log_dir", "", "If non-empty, write log files in this directory")
var logDir *string = new(string)

func createLogDirs() {
    if *logDir != "" {
        logDirs = append(logDirs, *logDir)
    }
    logDirs = append(logDirs, os.TempDir())
}

var (
    pid      = os.Getpid()
    program  = filepath.Base(os.Args[0])
    host     = "unknownhost"
    userName = "unknownuser"
)

func init() {
    h, err := os.Hostname()
    if err == nil {
        host = shortHostname(h)
    }

    current, err := user.Current()
    if err == nil {
        userName = current.Username
    }

    // Sanitize userName since it may contain filepath separators on Windows.
    userName = strings.Replace(userName, `\`, "_", -1)
}

// shortHostname returns its argument, truncating at the first period.
// For instance, given "www.google.com" it returns "www".
func shortHostname(hostname string) string {
    if i := strings.Index(hostname, "."); i >= 0 {
        return hostname[:i]
    }
    return hostname
}

// logName returns a new log file name containing tag, with start time t, and
// the name for the symlink for tag.
func logName(tag string, t time.Time) (name, link string) {
    name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
        program,
        host,
        userName,
        tag,
        t.Year(),
        t.Month(),
        t.Day(),
        t.Hour(),
        t.Minute(),
        t.Second(),
        pid)
    return name, program + "." + tag
}

var onceLogDirs sync.Once

// create creates a new log file and returns the file and its filename, which
// contains tag ("INFO", "FATAL", etc.) and t.  If the file is created
// successfully, create also attempts to update the symlink for that tag, ignoring
// errors.
func create(tag string, t time.Time) (f *os.File, filename string, err error) {
    onceLogDirs.Do(createLogDirs)
    if len(logDirs) == 0 {
        return nil, "", errors.New("log: no log dirs")
    }
    name, link := logName(tag, t)
    var lastErr error
    for _, dir := range logDirs {
        fname := filepath.Join(dir, name)
        f, err := os.Create(fname)
        if err == nil {
            symlink := filepath.Join(dir, link)
            os.Remove(symlink)        // ignore err
            os.Symlink(name, symlink) // ignore err
            return f, fname, nil
        }
        lastErr = err
    }
    return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
}