This file is indexed.

/usr/share/gocode/src/github.com/juju/loggo/writer.go is in golang-github-juju-loggo-dev 0.0~git20150527.0.8477fc9-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package loggo

import (
	"fmt"
	"io"
	"os"
	"sync"
	"time"
)

// Writer is implemented by any recipient of log messages.
type Writer interface {
	// Write writes a message to the Writer with the given
	// level and module name. The filename and line hold
	// the file name and line number of the code that is
	// generating the log message; the time stamp holds
	// the time the log message was generated, and
	// message holds the log message itself.
	Write(level Level, name, filename string, line int, timestamp time.Time, message string)
}

type registeredWriter struct {
	writer Writer
	level  Level
}

// defaultName is the name of a writer that is registered
// by default that writes to stderr.
const defaultName = "default"

var (
	writerMutex sync.Mutex
	writers     = map[string]*registeredWriter{
		defaultName: &registeredWriter{
			writer: NewSimpleWriter(os.Stderr, &DefaultFormatter{}),
			level:  TRACE,
		},
	}
	globalMinLevel = TRACE
)

// ResetWriters puts the list of writers back into the initial state.
func ResetWriters() {
	writerMutex.Lock()
	defer writerMutex.Unlock()
	writers = map[string]*registeredWriter{
		"default": &registeredWriter{
			writer: NewSimpleWriter(os.Stderr, &DefaultFormatter{}),
			level:  TRACE,
		},
	}
	findMinLevel()
}

// ReplaceDefaultWriter is a convenience method that does the equivalent of
// RemoveWriter and then RegisterWriter with the name "default".  The previous
// default writer, if any is returned.
func ReplaceDefaultWriter(writer Writer) (Writer, error) {
	if writer == nil {
		return nil, fmt.Errorf("Writer cannot be nil")
	}
	writerMutex.Lock()
	defer writerMutex.Unlock()
	reg, found := writers[defaultName]
	if !found {
		return nil, fmt.Errorf("there is no %q writer", defaultName)
	}
	oldWriter := reg.writer
	reg.writer = writer
	return oldWriter, nil

}

// RegisterWriter adds the writer to the list of writers that get notified
// when logging.  When registering, the caller specifies the minimum logging
// level that will be written, and a name for the writer.  If there is already
// a registered writer with that name, an error is returned.
func RegisterWriter(name string, writer Writer, minLevel Level) error {
	if writer == nil {
		return fmt.Errorf("Writer cannot be nil")
	}
	writerMutex.Lock()
	defer writerMutex.Unlock()
	if _, found := writers[name]; found {
		return fmt.Errorf("there is already a Writer registered with the name %q", name)
	}
	writers[name] = &registeredWriter{writer: writer, level: minLevel}
	findMinLevel()
	return nil
}

// RemoveWriter removes the Writer identified by 'name' and returns it.
// If the Writer is not found, an error is returned.
func RemoveWriter(name string) (Writer, Level, error) {
	writerMutex.Lock()
	defer writerMutex.Unlock()
	registered, found := writers[name]
	if !found {
		return nil, UNSPECIFIED, fmt.Errorf("Writer %q is not registered", name)
	}
	delete(writers, name)
	findMinLevel()
	return registered.writer, registered.level, nil
}

func findMinLevel() {
	// We assume the lock is already held
	minLevel := CRITICAL
	for _, registered := range writers {
		if registered.level < minLevel {
			minLevel = registered.level
		}
	}
	globalMinLevel.set(minLevel)
}

// WillWrite returns whether there are any writers registered
// at or above the given severity level. If it returns
// false, a log message at the given level will be discarded.
func WillWrite(level Level) bool {
	return level >= globalMinLevel.get()
}

func writeToWriters(level Level, module, filename string, line int, timestamp time.Time, message string) {
	writerMutex.Lock()
	defer writerMutex.Unlock()
	for _, registered := range writers {
		if level >= registered.level {
			registered.writer.Write(level, module, filename, line, timestamp, message)
		}
	}
}

type simpleWriter struct {
	writer    io.Writer
	formatter Formatter
}

// NewSimpleWriter returns a new writer that writes
// log messages to the given io.Writer formatting the
// messages with the given formatter.
func NewSimpleWriter(writer io.Writer, formatter Formatter) Writer {
	return &simpleWriter{writer, formatter}
}

func (simple *simpleWriter) Write(level Level, module, filename string, line int, timestamp time.Time, message string) {
	logLine := simple.formatter.Format(level, module, filename, line, timestamp, message)
	fmt.Fprintln(simple.writer, logLine)
}