mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 10:25:42 +03:00
Merge pull request #5739 from hashicorp/r-rm-logmon-syslog-deadcode
logmon: remove syslog server deadcode
This commit is contained in:
@@ -1,159 +0,0 @@
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
syslog "github.com/RackSec/srslog"
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
// Errors related to parsing priority
|
||||
var (
|
||||
ErrPriorityNoStart = fmt.Errorf("No start char found for priority")
|
||||
ErrPriorityEmpty = fmt.Errorf("Priority field empty")
|
||||
ErrPriorityNoEnd = fmt.Errorf("No end char found for priority")
|
||||
ErrPriorityTooShort = fmt.Errorf("Priority field too short")
|
||||
ErrPriorityTooLong = fmt.Errorf("Priority field too long")
|
||||
ErrPriorityNonDigit = fmt.Errorf("Non digit found in priority")
|
||||
)
|
||||
|
||||
// Priority header and ending characters
|
||||
const (
|
||||
PRI_PART_START = '<'
|
||||
PRI_PART_END = '>'
|
||||
)
|
||||
|
||||
// SyslogMessage represents a log line received
|
||||
type SyslogMessage struct {
|
||||
Message []byte
|
||||
Severity syslog.Priority
|
||||
}
|
||||
|
||||
// Priority holds all the priority bits in a syslog log line
|
||||
type Priority struct {
|
||||
Pri int
|
||||
Facility syslog.Priority
|
||||
Severity syslog.Priority
|
||||
}
|
||||
|
||||
// DockerLogParser parses a line of log message that the docker daemon ships
|
||||
type DockerLogParser struct {
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
// NewDockerLogParser creates a new DockerLogParser
|
||||
func NewDockerLogParser(logger hclog.Logger) *DockerLogParser {
|
||||
return &DockerLogParser{logger: logger}
|
||||
}
|
||||
|
||||
// Parse parses a syslog log line
|
||||
func (d *DockerLogParser) Parse(line []byte) *SyslogMessage {
|
||||
pri, _, _ := d.parsePriority(line)
|
||||
msgIdx := d.logContentIndex(line)
|
||||
|
||||
// Create a copy of the line so that subsequent Scans do not override the
|
||||
// message
|
||||
lineCopy := make([]byte, len(line[msgIdx:]))
|
||||
copy(lineCopy, line[msgIdx:])
|
||||
|
||||
return &SyslogMessage{
|
||||
Severity: pri.Severity,
|
||||
Message: lineCopy,
|
||||
}
|
||||
}
|
||||
|
||||
// logContentIndex finds out the index of the start index of the content in a
|
||||
// syslog line
|
||||
func (d *DockerLogParser) logContentIndex(line []byte) int {
|
||||
cursor := 0
|
||||
numSpace := 0
|
||||
numColons := 0
|
||||
// first look for at least 2 colons. This matches into the date that has no more spaces in it
|
||||
// DefaultFormatter log line look: '<30>2016-07-06T15:13:11Z00:00 hostname docker/9648c64f5037[16200]'
|
||||
// UnixFormatter log line look: '<30>Jul 6 15:13:11 docker/9648c64f5037[16200]'
|
||||
for i := 0; i < len(line); i++ {
|
||||
if line[i] == ':' {
|
||||
numColons += 1
|
||||
if numColons == 2 {
|
||||
cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// then look for the next space
|
||||
for i := cursor; i < len(line); i++ {
|
||||
if line[i] == ' ' {
|
||||
numSpace += 1
|
||||
if numSpace == 1 {
|
||||
cursor = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// then the colon is what separates it, followed by a space
|
||||
for i := cursor; i < len(line); i++ {
|
||||
if line[i] == ':' && i+1 < len(line) && line[i+1] == ' ' {
|
||||
cursor = i + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
// return the cursor to the next character
|
||||
return cursor + 1
|
||||
}
|
||||
|
||||
// parsePriority parses the priority in a syslog message
|
||||
func (d *DockerLogParser) parsePriority(line []byte) (Priority, int, error) {
|
||||
cursor := 0
|
||||
pri := d.newPriority(0)
|
||||
if len(line) <= 0 {
|
||||
return pri, cursor, ErrPriorityEmpty
|
||||
}
|
||||
if line[cursor] != PRI_PART_START {
|
||||
return pri, cursor, ErrPriorityNoStart
|
||||
}
|
||||
i := 1
|
||||
priDigit := 0
|
||||
for i < len(line) {
|
||||
if i >= 5 {
|
||||
return pri, cursor, ErrPriorityTooLong
|
||||
}
|
||||
c := line[i]
|
||||
if c == PRI_PART_END {
|
||||
if i == 1 {
|
||||
return pri, cursor, ErrPriorityTooShort
|
||||
}
|
||||
cursor = i + 1
|
||||
return d.newPriority(priDigit), cursor, nil
|
||||
}
|
||||
if d.isDigit(c) {
|
||||
v, e := strconv.Atoi(string(c))
|
||||
if e != nil {
|
||||
return pri, cursor, e
|
||||
}
|
||||
priDigit = (priDigit * 10) + v
|
||||
} else {
|
||||
return pri, cursor, ErrPriorityNonDigit
|
||||
}
|
||||
i++
|
||||
}
|
||||
return pri, cursor, ErrPriorityNoEnd
|
||||
}
|
||||
|
||||
// isDigit checks if a byte is a numeric char
|
||||
func (d *DockerLogParser) isDigit(c byte) bool {
|
||||
return c >= '0' && c <= '9'
|
||||
}
|
||||
|
||||
// newPriority creates a new default priority
|
||||
func (d *DockerLogParser) newPriority(p int) Priority {
|
||||
// The Priority value is calculated by first multiplying the Facility
|
||||
// number by 8 and then adding the numerical value of the Severity.
|
||||
return Priority{
|
||||
Pri: p,
|
||||
Facility: syslog.Priority(p / 8),
|
||||
Severity: syslog.Priority(p % 8),
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
syslog "github.com/RackSec/srslog"
|
||||
"github.com/hashicorp/nomad/helper/testlog"
|
||||
)
|
||||
|
||||
func TestLogParser_Priority(t *testing.T) {
|
||||
t.Parallel()
|
||||
line := []byte("<30>2016-02-10T10:16:43-08:00 d-thinkpad docker/e2a1e3ebd3a3[22950]: 1:C 10 Feb 18:16:43.391 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf")
|
||||
d := NewDockerLogParser(testlog.HCLogger(t))
|
||||
p, _, err := d.parsePriority(line)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %v", err)
|
||||
}
|
||||
if p.Severity != syslog.LOG_INFO {
|
||||
t.Fatalf("expected severity: %v, got: %v", syslog.LOG_INFO, p.Severity)
|
||||
}
|
||||
|
||||
idx := d.logContentIndex(line)
|
||||
expected := bytes.Index(line, []byte("1:C 10 Feb 18:16:43.391"))
|
||||
if idx != expected {
|
||||
t.Fatalf("expected idx: %v, got: %v", expected, idx)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogParser_Priority_UnixFormatter(t *testing.T) {
|
||||
t.Parallel()
|
||||
line := []byte("<30>Feb 6, 10:16:43 docker/e2a1e3ebd3a3[22950]: 1:C 10 Feb 18:16:43.391 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf")
|
||||
d := NewDockerLogParser(testlog.HCLogger(t))
|
||||
p, _, err := d.parsePriority(line)
|
||||
if err != nil {
|
||||
t.Fatalf("got an err: %v", err)
|
||||
}
|
||||
if p.Severity != syslog.LOG_INFO {
|
||||
t.Fatalf("expected severity: %v, got: %v", syslog.LOG_INFO, p.Severity)
|
||||
}
|
||||
|
||||
idx := d.logContentIndex(line)
|
||||
expected := bytes.Index(line, []byte("1:C 10 Feb 18:16:43.391"))
|
||||
if idx != expected {
|
||||
t.Fatalf("expected idx: %v, got: %v", expected, idx)
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
)
|
||||
|
||||
// SyslogServer is a server which listens to syslog messages and parses them
|
||||
type SyslogServer struct {
|
||||
listener net.Listener
|
||||
messages chan *SyslogMessage
|
||||
parser *DockerLogParser
|
||||
|
||||
doneCh chan interface{}
|
||||
done bool
|
||||
doneLock sync.Mutex
|
||||
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
// NewSyslogServer creates a new syslog server
|
||||
func NewSyslogServer(l net.Listener, messages chan *SyslogMessage, logger hclog.Logger) *SyslogServer {
|
||||
logger = logger.Named("logcollector.server")
|
||||
parser := NewDockerLogParser(logger)
|
||||
return &SyslogServer{
|
||||
listener: l,
|
||||
messages: messages,
|
||||
parser: parser,
|
||||
logger: logger,
|
||||
doneCh: make(chan interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts accepting syslog connections
|
||||
func (s *SyslogServer) Start() {
|
||||
for {
|
||||
select {
|
||||
case <-s.doneCh:
|
||||
return
|
||||
default:
|
||||
connection, err := s.listener.Accept()
|
||||
if err != nil {
|
||||
s.doneLock.Lock()
|
||||
done := s.done
|
||||
s.doneLock.Unlock()
|
||||
if done {
|
||||
return
|
||||
}
|
||||
|
||||
s.logger.Error("error in accepting connection", "err", err)
|
||||
continue
|
||||
}
|
||||
go s.read(connection)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read reads the bytes from a connection
|
||||
func (s *SyslogServer) read(connection net.Conn) {
|
||||
defer connection.Close()
|
||||
scanner := bufio.NewScanner(bufio.NewReader(connection))
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.doneCh:
|
||||
return
|
||||
default:
|
||||
}
|
||||
if scanner.Scan() {
|
||||
b := scanner.Bytes()
|
||||
msg := s.parser.Parse(b)
|
||||
s.messages <- msg
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown the syslog server
|
||||
func (s *SyslogServer) Shutdown() {
|
||||
s.doneLock.Lock()
|
||||
defer s.doneLock.Unlock()
|
||||
|
||||
if !s.done {
|
||||
close(s.doneCh)
|
||||
close(s.messages)
|
||||
s.done = true
|
||||
s.listener.Close()
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/helper/testlog"
|
||||
)
|
||||
|
||||
func TestSyslogServer_Start_Shutdown(t *testing.T) {
|
||||
t.Parallel()
|
||||
dir, err := ioutil.TempDir("", "sock")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temporary directory: %v", err)
|
||||
}
|
||||
|
||||
sock := path.Join(dir, "socket")
|
||||
defer os.Remove(sock)
|
||||
|
||||
l, err := net.Listen("unix", sock)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to listen unix socket: %v", err)
|
||||
}
|
||||
|
||||
s := NewSyslogServer(l, make(chan *SyslogMessage, 2048), testlog.HCLogger(t))
|
||||
|
||||
go s.Start()
|
||||
if s.done {
|
||||
t.Fatalf("expected running SyslogServer, but not running")
|
||||
}
|
||||
|
||||
received := false
|
||||
go func() {
|
||||
for range s.messages {
|
||||
received = true
|
||||
}
|
||||
}()
|
||||
|
||||
conn, err := net.Dial("unix", sock)
|
||||
if err != nil {
|
||||
t.Fatalf("expected access to SyslogServer, but %v", err)
|
||||
}
|
||||
|
||||
_, err = conn.Write([]byte("syslog server test\n"))
|
||||
if err != nil {
|
||||
t.Fatalf("expected send data to SyslogServer but: %v", err)
|
||||
}
|
||||
|
||||
// Need to wait until SyslogServer received the data certainly
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
|
||||
if !received {
|
||||
t.Fatalf("expected SyslogServer received data, but not received")
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
s.Shutdown()
|
||||
if !s.done {
|
||||
t.Fatalf("expected SyslogServer done, but running")
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
|
||||
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
syslog "github.com/RackSec/srslog"
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
// LogCollectorContext holds context to configure the syslog server
|
||||
type LogCollectorContext struct {
|
||||
// TaskName is the name of the Task
|
||||
TaskName string
|
||||
|
||||
// AllocDir is the handle to do operations on the alloc dir of
|
||||
// the task
|
||||
AllocDir *allocdir.AllocDir
|
||||
|
||||
// LogConfig provides configuration related to log rotation
|
||||
LogConfig *structs.LogConfig
|
||||
|
||||
// PortUpperBound is the upper bound of the ports that we can use to start
|
||||
// the syslog server
|
||||
PortUpperBound uint
|
||||
|
||||
// PortLowerBound is the lower bound of the ports that we can use to start
|
||||
// the syslog server
|
||||
PortLowerBound uint
|
||||
}
|
||||
|
||||
// SyslogCollectorState holds the address and isolation information of a launched
|
||||
// syslog server
|
||||
type SyslogCollectorState struct {
|
||||
Addr string
|
||||
}
|
||||
|
||||
// LogCollector is an interface which allows a driver to launch a log server
|
||||
// and update log configuration
|
||||
type LogCollector interface {
|
||||
LaunchCollector(ctx *LogCollectorContext) (*SyslogCollectorState, error)
|
||||
Exit() error
|
||||
UpdateLogConfig(logConfig *structs.LogConfig) error
|
||||
}
|
||||
|
||||
// SyslogCollector is a LogCollector which starts a syslog server and does
|
||||
// rotation to incoming stream
|
||||
type SyslogCollector struct {
|
||||
ctx *LogCollectorContext
|
||||
|
||||
lro *FileRotator
|
||||
lre *FileRotator
|
||||
server *SyslogServer
|
||||
syslogChan chan *SyslogMessage
|
||||
taskDir string
|
||||
|
||||
logger hclog.Logger
|
||||
}
|
||||
|
||||
// NewSyslogCollector returns an implementation of the SyslogCollector
|
||||
func NewSyslogCollector(logger hclog.Logger) *SyslogCollector {
|
||||
return &SyslogCollector{logger: logger.Named("syslog-server"),
|
||||
syslogChan: make(chan *SyslogMessage, 2048)}
|
||||
}
|
||||
|
||||
// LaunchCollector launches a new syslog server and starts writing log lines to
|
||||
// files and rotates them
|
||||
func (s *SyslogCollector) LaunchCollector(ctx *LogCollectorContext) (*SyslogCollectorState, error) {
|
||||
l, err := s.getListener(ctx.PortLowerBound, ctx.PortUpperBound)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.logger.Debug("launching syslog server on addr", "addr", l.Addr().String())
|
||||
s.ctx = ctx
|
||||
// configuring the task dir
|
||||
if err := s.configureTaskDir(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.server = NewSyslogServer(l, s.syslogChan, s.logger)
|
||||
go s.server.Start()
|
||||
logFileSize := int64(ctx.LogConfig.MaxFileSizeMB * 1024 * 1024)
|
||||
|
||||
//FIXME There's an easier way to get this
|
||||
logdir := ctx.AllocDir.TaskDirs[ctx.TaskName].LogDir
|
||||
lro, err := NewFileRotator(logdir, fmt.Sprintf("%v.stdout", ctx.TaskName),
|
||||
ctx.LogConfig.MaxFiles, logFileSize, s.logger)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.lro = lro
|
||||
|
||||
lre, err := NewFileRotator(logdir, fmt.Sprintf("%v.stderr", ctx.TaskName),
|
||||
ctx.LogConfig.MaxFiles, logFileSize, s.logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.lre = lre
|
||||
|
||||
go s.collectLogs(lre, lro)
|
||||
syslogAddr := fmt.Sprintf("%s://%s", l.Addr().Network(), l.Addr().String())
|
||||
return &SyslogCollectorState{Addr: syslogAddr}, nil
|
||||
}
|
||||
|
||||
func (s *SyslogCollector) collectLogs(we io.Writer, wo io.Writer) {
|
||||
for logParts := range s.syslogChan {
|
||||
// If the severity of the log line is err then we write to stderr
|
||||
// otherwise all messages go to stdout
|
||||
if logParts.Severity == syslog.LOG_ERR {
|
||||
s.lre.Write(logParts.Message)
|
||||
s.lre.Write([]byte{'\n'})
|
||||
} else {
|
||||
s.lro.Write(logParts.Message)
|
||||
s.lro.Write([]byte{'\n'})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit kills the syslog server
|
||||
func (s *SyslogCollector) Exit() error {
|
||||
s.server.Shutdown()
|
||||
s.lre.Close()
|
||||
s.lro.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLogConfig updates the log configuration
|
||||
func (s *SyslogCollector) UpdateLogConfig(logConfig *structs.LogConfig) error {
|
||||
s.ctx.LogConfig = logConfig
|
||||
if s.lro == nil {
|
||||
return fmt.Errorf("log rotator for stdout doesn't exist")
|
||||
}
|
||||
s.lro.MaxFiles = logConfig.MaxFiles
|
||||
s.lro.FileSize = int64(logConfig.MaxFileSizeMB * 1024 * 1024)
|
||||
|
||||
if s.lre == nil {
|
||||
return fmt.Errorf("log rotator for stderr doesn't exist")
|
||||
}
|
||||
s.lre.MaxFiles = logConfig.MaxFiles
|
||||
s.lre.FileSize = int64(logConfig.MaxFileSizeMB * 1024 * 1024)
|
||||
return nil
|
||||
}
|
||||
|
||||
// configureTaskDir sets the task dir in the SyslogCollector
|
||||
func (s *SyslogCollector) configureTaskDir() error {
|
||||
taskDir, ok := s.ctx.AllocDir.TaskDirs[s.ctx.TaskName]
|
||||
if !ok {
|
||||
return fmt.Errorf("couldn't find task directory for task %v", s.ctx.TaskName)
|
||||
}
|
||||
s.taskDir = taskDir.Dir
|
||||
return nil
|
||||
}
|
||||
|
||||
// getFreePort returns a free port ready to be listened on between upper and
|
||||
// lower bounds
|
||||
func (s *SyslogCollector) getListener(lowerBound uint, upperBound uint) (net.Listener, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
return s.listenerTCP(lowerBound, upperBound)
|
||||
}
|
||||
|
||||
return s.listenerUnix()
|
||||
}
|
||||
|
||||
// listenerTCP creates a TCP listener using an unused port between an upper and
|
||||
// lower bound
|
||||
func (s *SyslogCollector) listenerTCP(lowerBound uint, upperBound uint) (net.Listener, error) {
|
||||
for i := lowerBound; i <= upperBound; i++ {
|
||||
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("localhost:%v", i))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l, err := net.ListenTCP("tcp", addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
return nil, fmt.Errorf("No free port found")
|
||||
}
|
||||
|
||||
// listenerUnix creates a Unix domain socket
|
||||
func (s *SyslogCollector) listenerUnix() (net.Listener, error) {
|
||||
f, err := ioutil.TempFile("", "plugin")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := f.Name()
|
||||
|
||||
if err := f.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := os.Remove(path); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return net.Listen("unix", path)
|
||||
}
|
||||
50
vendor/github.com/RackSec/srslog/CODE_OF_CONDUCT.md
generated
vendored
50
vendor/github.com/RackSec/srslog/CODE_OF_CONDUCT.md
generated
vendored
@@ -1,50 +0,0 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of
|
||||
fostering an open and welcoming community, we pledge to respect all people who
|
||||
contribute through reporting issues, posting feature requests, updating
|
||||
documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free
|
||||
experience for everyone, regardless of level of experience, gender, gender
|
||||
identity and expression, sexual orientation, disability, personal appearance,
|
||||
body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic
|
||||
addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to
|
||||
fairly and consistently applying these principles to every aspect of managing
|
||||
this project. Project maintainers who do not follow or enforce the Code of
|
||||
Conduct may be permanently removed from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting a project maintainer at [sirsean@gmail.com]. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. Maintainers are
|
||||
obligated to maintain confidentiality with regard to the reporter of an
|
||||
incident.
|
||||
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 1.3.0, available at
|
||||
[http://contributor-covenant.org/version/1/3/0/][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/3/0/
|
||||
27
vendor/github.com/RackSec/srslog/LICENSE
generated
vendored
27
vendor/github.com/RackSec/srslog/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright (c) 2015 Rackspace. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
131
vendor/github.com/RackSec/srslog/README.md
generated
vendored
131
vendor/github.com/RackSec/srslog/README.md
generated
vendored
@@ -1,131 +0,0 @@
|
||||
[](https://travis-ci.org/RackSec/srslog)
|
||||
|
||||
# srslog
|
||||
|
||||
Go has a `syslog` package in the standard library, but it has the following
|
||||
shortcomings:
|
||||
|
||||
1. It doesn't have TLS support
|
||||
2. [According to bradfitz on the Go team, it is no longer being maintained.](https://github.com/golang/go/issues/13449#issuecomment-161204716)
|
||||
|
||||
I agree that it doesn't need to be in the standard library. So, I've
|
||||
followed Brad's suggestion and have made a separate project to handle syslog.
|
||||
|
||||
This code was taken directly from the Go project as a base to start from.
|
||||
|
||||
However, this _does_ have TLS support.
|
||||
|
||||
# Usage
|
||||
|
||||
Basic usage retains the same interface as the original `syslog` package. We
|
||||
only added to the interface where required to support new functionality.
|
||||
|
||||
Switch from the standard library:
|
||||
|
||||
```
|
||||
import(
|
||||
//"log/syslog"
|
||||
syslog "github.com/RackSec/srslog"
|
||||
)
|
||||
```
|
||||
|
||||
You can still use it for local syslog:
|
||||
|
||||
```
|
||||
w, err := syslog.Dial("", "", syslog.LOG_ERR, "testtag")
|
||||
```
|
||||
|
||||
Or to unencrypted UDP:
|
||||
|
||||
```
|
||||
w, err := syslog.Dial("udp", "192.168.0.50:514", syslog.LOG_ERR, "testtag")
|
||||
```
|
||||
|
||||
Or to unencrypted TCP:
|
||||
|
||||
```
|
||||
w, err := syslog.Dial("tcp", "192.168.0.51:514", syslog.LOG_ERR, "testtag")
|
||||
```
|
||||
|
||||
But now you can also send messages via TLS-encrypted TCP:
|
||||
|
||||
```
|
||||
w, err := syslog.DialWithTLSCertPath("tcp+tls", "192.168.0.52:514", syslog.LOG_ERR, "testtag", "/path/to/servercert.pem")
|
||||
```
|
||||
|
||||
And if you need more control over your TLS configuration :
|
||||
|
||||
```
|
||||
pool := x509.NewCertPool()
|
||||
serverCert, err := ioutil.ReadFile("/path/to/servercert.pem")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool.AppendCertsFromPEM(serverCert)
|
||||
config := tls.Config{
|
||||
RootCAs: pool,
|
||||
}
|
||||
|
||||
w, err := DialWithTLSConfig(network, raddr, priority, tag, &config)
|
||||
```
|
||||
|
||||
(Note that in both TLS cases, this uses a self-signed certificate, where the
|
||||
remote syslog server has the keypair and the client has only the public key.)
|
||||
|
||||
And then to write log messages, continue like so:
|
||||
|
||||
```
|
||||
if err != nil {
|
||||
log.Fatal("failed to connect to syslog:", err)
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
w.Alert("this is an alert")
|
||||
w.Crit("this is critical")
|
||||
w.Err("this is an error")
|
||||
w.Warning("this is a warning")
|
||||
w.Notice("this is a notice")
|
||||
w.Info("this is info")
|
||||
w.Debug("this is debug")
|
||||
w.Write([]byte("these are some bytes"))
|
||||
```
|
||||
|
||||
# Generating TLS Certificates
|
||||
|
||||
We've provided a script that you can use to generate a self-signed keypair:
|
||||
|
||||
```
|
||||
pip install cryptography
|
||||
python script/gen-certs.py
|
||||
```
|
||||
|
||||
That outputs the public key and private key to standard out. Put those into
|
||||
`.pem` files. (And don't put them into any source control. The certificate in
|
||||
the `test` directory is used by the unit tests, and please do not actually use
|
||||
it anywhere else.)
|
||||
|
||||
# Running Tests
|
||||
|
||||
Run the tests as usual:
|
||||
|
||||
```
|
||||
go test
|
||||
```
|
||||
|
||||
But we've also provided a test coverage script that will show you which
|
||||
lines of code are not covered:
|
||||
|
||||
```
|
||||
script/coverage --html
|
||||
```
|
||||
|
||||
That will open a new browser tab showing coverage information.
|
||||
|
||||
# License
|
||||
|
||||
This project uses the New BSD License, the same as the Go project itself.
|
||||
|
||||
# Code of Conduct
|
||||
|
||||
Please note that this project is released with a Contributor Code of Conduct.
|
||||
By participating in this project you agree to abide by its terms.
|
||||
68
vendor/github.com/RackSec/srslog/constants.go
generated
vendored
68
vendor/github.com/RackSec/srslog/constants.go
generated
vendored
@@ -1,68 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Priority is a combination of the syslog facility and
|
||||
// severity. For example, LOG_ALERT | LOG_FTP sends an alert severity
|
||||
// message from the FTP facility. The default severity is LOG_EMERG;
|
||||
// the default facility is LOG_KERN.
|
||||
type Priority int
|
||||
|
||||
const severityMask = 0x07
|
||||
const facilityMask = 0xf8
|
||||
|
||||
const (
|
||||
// Severity.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same on Linux, BSD, and OS X.
|
||||
LOG_EMERG Priority = iota
|
||||
LOG_ALERT
|
||||
LOG_CRIT
|
||||
LOG_ERR
|
||||
LOG_WARNING
|
||||
LOG_NOTICE
|
||||
LOG_INFO
|
||||
LOG_DEBUG
|
||||
)
|
||||
|
||||
const (
|
||||
// Facility.
|
||||
|
||||
// From /usr/include/sys/syslog.h.
|
||||
// These are the same up to LOG_FTP on Linux, BSD, and OS X.
|
||||
LOG_KERN Priority = iota << 3
|
||||
LOG_USER
|
||||
LOG_MAIL
|
||||
LOG_DAEMON
|
||||
LOG_AUTH
|
||||
LOG_SYSLOG
|
||||
LOG_LPR
|
||||
LOG_NEWS
|
||||
LOG_UUCP
|
||||
LOG_CRON
|
||||
LOG_AUTHPRIV
|
||||
LOG_FTP
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
_ // unused
|
||||
LOG_LOCAL0
|
||||
LOG_LOCAL1
|
||||
LOG_LOCAL2
|
||||
LOG_LOCAL3
|
||||
LOG_LOCAL4
|
||||
LOG_LOCAL5
|
||||
LOG_LOCAL6
|
||||
LOG_LOCAL7
|
||||
)
|
||||
|
||||
func validatePriority(p Priority) error {
|
||||
if p < 0 || p > LOG_LOCAL7|LOG_DEBUG {
|
||||
return errors.New("log/syslog: invalid priority")
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
87
vendor/github.com/RackSec/srslog/dialer.go
generated
vendored
87
vendor/github.com/RackSec/srslog/dialer.go
generated
vendored
@@ -1,87 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
)
|
||||
|
||||
// dialerFunctionWrapper is a simple object that consists of a dialer function
|
||||
// and its name. This is primarily for testing, so we can make sure that the
|
||||
// getDialer method returns the correct dialer function. However, if you ever
|
||||
// find that you need to check which dialer function you have, this would also
|
||||
// be useful for you without having to use reflection.
|
||||
type dialerFunctionWrapper struct {
|
||||
Name string
|
||||
Dialer func() (serverConn, string, error)
|
||||
}
|
||||
|
||||
// Call the wrapped dialer function and return its return values.
|
||||
func (df dialerFunctionWrapper) Call() (serverConn, string, error) {
|
||||
return df.Dialer()
|
||||
}
|
||||
|
||||
// getDialer returns a "dialer" function that can be called to connect to a
|
||||
// syslog server.
|
||||
//
|
||||
// Each dialer function is responsible for dialing the remote host and returns
|
||||
// a serverConn, the hostname (or a default if the Writer has not specified a
|
||||
// hostname), and an error in case dialing fails.
|
||||
//
|
||||
// The reason for separate dialers is that different network types may need
|
||||
// to dial their connection differently, yet still provide a net.Conn interface
|
||||
// that you can use once they have dialed. Rather than an increasingly long
|
||||
// conditional, we have a map of network -> dialer function (with a sane default
|
||||
// value), and adding a new network type is as easy as writing the dialer
|
||||
// function and adding it to the map.
|
||||
func (w *Writer) getDialer() dialerFunctionWrapper {
|
||||
dialers := map[string]dialerFunctionWrapper{
|
||||
"": dialerFunctionWrapper{"unixDialer", w.unixDialer},
|
||||
"tcp+tls": dialerFunctionWrapper{"tlsDialer", w.tlsDialer},
|
||||
}
|
||||
dialer, ok := dialers[w.network]
|
||||
if !ok {
|
||||
dialer = dialerFunctionWrapper{"basicDialer", w.basicDialer}
|
||||
}
|
||||
return dialer
|
||||
}
|
||||
|
||||
// unixDialer uses the unixSyslog method to open a connection to the syslog
|
||||
// daemon running on the local machine.
|
||||
func (w *Writer) unixDialer() (serverConn, string, error) {
|
||||
sc, err := unixSyslog()
|
||||
hostname := w.hostname
|
||||
if hostname == "" {
|
||||
hostname = "localhost"
|
||||
}
|
||||
return sc, hostname, err
|
||||
}
|
||||
|
||||
// tlsDialer connects to TLS over TCP, and is used for the "tcp+tls" network
|
||||
// type.
|
||||
func (w *Writer) tlsDialer() (serverConn, string, error) {
|
||||
c, err := tls.Dial("tcp", w.raddr, w.tlsConfig)
|
||||
var sc serverConn
|
||||
hostname := w.hostname
|
||||
if err == nil {
|
||||
sc = &netConn{conn: c}
|
||||
if hostname == "" {
|
||||
hostname = c.LocalAddr().String()
|
||||
}
|
||||
}
|
||||
return sc, hostname, err
|
||||
}
|
||||
|
||||
// basicDialer is the most common dialer for syslog, and supports both TCP and
|
||||
// UDP connections.
|
||||
func (w *Writer) basicDialer() (serverConn, string, error) {
|
||||
c, err := net.Dial(w.network, w.raddr)
|
||||
var sc serverConn
|
||||
hostname := w.hostname
|
||||
if err == nil {
|
||||
sc = &netConn{conn: c}
|
||||
if hostname == "" {
|
||||
hostname = c.LocalAddr().String()
|
||||
}
|
||||
}
|
||||
return sc, hostname, err
|
||||
}
|
||||
48
vendor/github.com/RackSec/srslog/formatter.go
generated
vendored
48
vendor/github.com/RackSec/srslog/formatter.go
generated
vendored
@@ -1,48 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Formatter is a type of function that takes the consituent parts of a
|
||||
// syslog message and returns a formatted string. A different Formatter is
|
||||
// defined for each different syslog protocol we support.
|
||||
type Formatter func(p Priority, hostname, tag, content string) string
|
||||
|
||||
// DefaultFormatter is the original format supported by the Go syslog package,
|
||||
// and is a non-compliant amalgamation of 3164 and 5424 that is intended to
|
||||
// maximize compatibility.
|
||||
func DefaultFormatter(p Priority, hostname, tag, content string) string {
|
||||
timestamp := time.Now().Format(time.RFC3339)
|
||||
msg := fmt.Sprintf("<%d> %s %s %s[%d]: %s",
|
||||
p, timestamp, hostname, tag, os.Getpid(), content)
|
||||
return msg
|
||||
}
|
||||
|
||||
// UnixFormatter omits the hostname, because it is only used locally.
|
||||
func UnixFormatter(p Priority, hostname, tag, content string) string {
|
||||
timestamp := time.Now().Format(time.Stamp)
|
||||
msg := fmt.Sprintf("<%d>%s %s[%d]: %s",
|
||||
p, timestamp, tag, os.Getpid(), content)
|
||||
return msg
|
||||
}
|
||||
|
||||
// RFC3164Formatter provides an RFC 3164 compliant message.
|
||||
func RFC3164Formatter(p Priority, hostname, tag, content string) string {
|
||||
timestamp := time.Now().Format(time.Stamp)
|
||||
msg := fmt.Sprintf("<%d> %s %s %s[%d]: %s",
|
||||
p, timestamp, hostname, tag, os.Getpid(), content)
|
||||
return msg
|
||||
}
|
||||
|
||||
// RFC5424Formatter provides an RFC 5424 compliant message.
|
||||
func RFC5424Formatter(p Priority, hostname, tag, content string) string {
|
||||
timestamp := time.Now().Format(time.RFC3339)
|
||||
pid := os.Getpid()
|
||||
appName := os.Args[0]
|
||||
msg := fmt.Sprintf("<%d>%d %s %s %s %d %s %s",
|
||||
p, 1, timestamp, hostname, appName, pid, tag, content)
|
||||
return msg
|
||||
}
|
||||
24
vendor/github.com/RackSec/srslog/framer.go
generated
vendored
24
vendor/github.com/RackSec/srslog/framer.go
generated
vendored
@@ -1,24 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Framer is a type of function that takes an input string (typically an
|
||||
// already-formatted syslog message) and applies "message framing" to it. We
|
||||
// have different framers because different versions of the syslog protocol
|
||||
// and its transport requirements define different framing behavior.
|
||||
type Framer func(in string) string
|
||||
|
||||
// DefaultFramer does nothing, since there is no framing to apply. This is
|
||||
// the original behavior of the Go syslog package, and is also typically used
|
||||
// for UDP syslog.
|
||||
func DefaultFramer(in string) string {
|
||||
return in
|
||||
}
|
||||
|
||||
// RFC5425MessageLengthFramer prepends the message length to the front of the
|
||||
// provided message, as defined in RFC 5425.
|
||||
func RFC5425MessageLengthFramer(in string) string {
|
||||
return fmt.Sprintf("%d %s", len(in), in)
|
||||
}
|
||||
30
vendor/github.com/RackSec/srslog/net_conn.go
generated
vendored
30
vendor/github.com/RackSec/srslog/net_conn.go
generated
vendored
@@ -1,30 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// netConn has an internal net.Conn and adheres to the serverConn interface,
|
||||
// allowing us to send syslog messages over the network.
|
||||
type netConn struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
// writeString formats syslog messages using time.RFC3339 and includes the
|
||||
// hostname, and sends the message to the connection.
|
||||
func (n *netConn) writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, msg string) error {
|
||||
if framer == nil {
|
||||
framer = DefaultFramer
|
||||
}
|
||||
if formatter == nil {
|
||||
formatter = DefaultFormatter
|
||||
}
|
||||
formattedMessage := framer(formatter(p, hostname, tag, msg))
|
||||
_, err := n.conn.Write([]byte(formattedMessage))
|
||||
return err
|
||||
}
|
||||
|
||||
// close the network connection
|
||||
func (n *netConn) close() error {
|
||||
return n.conn.Close()
|
||||
}
|
||||
100
vendor/github.com/RackSec/srslog/srslog.go
generated
vendored
100
vendor/github.com/RackSec/srslog/srslog.go
generated
vendored
@@ -1,100 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// This interface allows us to work with both local and network connections,
|
||||
// and enables Solaris support (see syslog_unix.go).
|
||||
type serverConn interface {
|
||||
writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, s string) error
|
||||
close() error
|
||||
}
|
||||
|
||||
// New establishes a new connection to the system log daemon. Each
|
||||
// write to the returned Writer sends a log message with the given
|
||||
// priority and prefix.
|
||||
func New(priority Priority, tag string) (w *Writer, err error) {
|
||||
return Dial("", "", priority, tag)
|
||||
}
|
||||
|
||||
// Dial establishes a connection to a log daemon by connecting to
|
||||
// address raddr on the specified network. Each write to the returned
|
||||
// Writer sends a log message with the given facility, severity and
|
||||
// tag.
|
||||
// If network is empty, Dial will connect to the local syslog server.
|
||||
func Dial(network, raddr string, priority Priority, tag string) (*Writer, error) {
|
||||
return DialWithTLSConfig(network, raddr, priority, tag, nil)
|
||||
}
|
||||
|
||||
// DialWithTLSCertPath establishes a secure connection to a log daemon by connecting to
|
||||
// address raddr on the specified network. It uses certPath to load TLS certificates and configure
|
||||
// the secure connection.
|
||||
func DialWithTLSCertPath(network, raddr string, priority Priority, tag, certPath string) (*Writer, error) {
|
||||
serverCert, err := ioutil.ReadFile(certPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return DialWithTLSCert(network, raddr, priority, tag, serverCert)
|
||||
}
|
||||
|
||||
// DialWIthTLSCert establishes a secure connection to a log daemon by connecting to
|
||||
// address raddr on the specified network. It uses serverCert to load a TLS certificate
|
||||
// and configure the secure connection.
|
||||
func DialWithTLSCert(network, raddr string, priority Priority, tag string, serverCert []byte) (*Writer, error) {
|
||||
pool := x509.NewCertPool()
|
||||
pool.AppendCertsFromPEM(serverCert)
|
||||
config := tls.Config{
|
||||
RootCAs: pool,
|
||||
}
|
||||
|
||||
return DialWithTLSConfig(network, raddr, priority, tag, &config)
|
||||
}
|
||||
|
||||
// DialWithTLSConfig establishes a secure connection to a log daemon by connecting to
|
||||
// address raddr on the specified network. It uses tlsConfig to configure the secure connection.
|
||||
func DialWithTLSConfig(network, raddr string, priority Priority, tag string, tlsConfig *tls.Config) (*Writer, error) {
|
||||
if err := validatePriority(priority); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tag == "" {
|
||||
tag = os.Args[0]
|
||||
}
|
||||
hostname, _ := os.Hostname()
|
||||
|
||||
w := &Writer{
|
||||
priority: priority,
|
||||
tag: tag,
|
||||
hostname: hostname,
|
||||
network: network,
|
||||
raddr: raddr,
|
||||
tlsConfig: tlsConfig,
|
||||
}
|
||||
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
err := w.connect()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return w, err
|
||||
}
|
||||
|
||||
// NewLogger creates a log.Logger whose output is written to
|
||||
// the system log service with the specified priority. The logFlag
|
||||
// argument is the flag set passed through to log.New to create
|
||||
// the Logger.
|
||||
func NewLogger(p Priority, logFlag int) (*log.Logger, error) {
|
||||
s, err := New(p, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return log.New(s, "", logFlag), nil
|
||||
}
|
||||
54
vendor/github.com/RackSec/srslog/srslog_unix.go
generated
vendored
54
vendor/github.com/RackSec/srslog/srslog_unix.go
generated
vendored
@@ -1,54 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
)
|
||||
|
||||
// unixSyslog opens a connection to the syslog daemon running on the
|
||||
// local machine using a Unix domain socket. This function exists because of
|
||||
// Solaris support as implemented by gccgo. On Solaris you can not
|
||||
// simply open a TCP connection to the syslog daemon. The gccgo
|
||||
// sources have a syslog_solaris.go file that implements unixSyslog to
|
||||
// return a type that satisfies the serverConn interface and simply calls the C
|
||||
// library syslog function.
|
||||
func unixSyslog() (conn serverConn, err error) {
|
||||
logTypes := []string{"unixgram", "unix"}
|
||||
logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"}
|
||||
for _, network := range logTypes {
|
||||
for _, path := range logPaths {
|
||||
conn, err := net.Dial(network, path)
|
||||
if err != nil {
|
||||
continue
|
||||
} else {
|
||||
return &localConn{conn: conn}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errors.New("Unix syslog delivery error")
|
||||
}
|
||||
|
||||
// localConn adheres to the serverConn interface, allowing us to send syslog
|
||||
// messages to the local syslog daemon over a Unix domain socket.
|
||||
type localConn struct {
|
||||
conn io.WriteCloser
|
||||
}
|
||||
|
||||
// writeString formats syslog messages using time.Stamp instead of time.RFC3339,
|
||||
// and omits the hostname (because it is expected to be used locally).
|
||||
func (n *localConn) writeString(framer Framer, formatter Formatter, p Priority, hostname, tag, msg string) error {
|
||||
if framer == nil {
|
||||
framer = DefaultFramer
|
||||
}
|
||||
if formatter == nil {
|
||||
formatter = UnixFormatter
|
||||
}
|
||||
_, err := n.conn.Write([]byte(framer(formatter(p, hostname, tag, msg))))
|
||||
return err
|
||||
}
|
||||
|
||||
// close the (local) network connection
|
||||
func (n *localConn) close() error {
|
||||
return n.conn.Close()
|
||||
}
|
||||
164
vendor/github.com/RackSec/srslog/writer.go
generated
vendored
164
vendor/github.com/RackSec/srslog/writer.go
generated
vendored
@@ -1,164 +0,0 @@
|
||||
package srslog
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A Writer is a connection to a syslog server.
|
||||
type Writer struct {
|
||||
sync.Mutex // guards conn
|
||||
|
||||
priority Priority
|
||||
tag string
|
||||
hostname string
|
||||
network string
|
||||
raddr string
|
||||
tlsConfig *tls.Config
|
||||
framer Framer
|
||||
formatter Formatter
|
||||
|
||||
conn serverConn
|
||||
}
|
||||
|
||||
// connect makes a connection to the syslog server.
|
||||
// It must be called with w.mu held.
|
||||
func (w *Writer) connect() (err error) {
|
||||
if w.conn != nil {
|
||||
// ignore err from close, it makes sense to continue anyway
|
||||
w.conn.close()
|
||||
w.conn = nil
|
||||
}
|
||||
|
||||
var conn serverConn
|
||||
var hostname string
|
||||
dialer := w.getDialer()
|
||||
conn, hostname, err = dialer.Call()
|
||||
if err == nil {
|
||||
w.conn = conn
|
||||
w.hostname = hostname
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetFormatter changes the formatter function for subsequent messages.
|
||||
func (w *Writer) SetFormatter(f Formatter) {
|
||||
w.formatter = f
|
||||
}
|
||||
|
||||
// SetFramer changes the framer function for subsequent messages.
|
||||
func (w *Writer) SetFramer(f Framer) {
|
||||
w.framer = f
|
||||
}
|
||||
|
||||
// Write sends a log message to the syslog daemon using the default priority
|
||||
// passed into `srslog.New` or the `srslog.Dial*` functions.
|
||||
func (w *Writer) Write(b []byte) (int, error) {
|
||||
return w.writeAndRetry(w.priority, string(b))
|
||||
}
|
||||
|
||||
// Close closes a connection to the syslog daemon.
|
||||
func (w *Writer) Close() error {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if w.conn != nil {
|
||||
err := w.conn.close()
|
||||
w.conn = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Emerg logs a message with severity LOG_EMERG; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Emerg(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_EMERG, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Alert logs a message with severity LOG_ALERT; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Alert(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_ALERT, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Crit logs a message with severity LOG_CRIT; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Crit(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_CRIT, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Err logs a message with severity LOG_ERR; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Err(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_ERR, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Warning logs a message with severity LOG_WARNING; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Warning(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_WARNING, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Notice logs a message with severity LOG_NOTICE; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Notice(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_NOTICE, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Info logs a message with severity LOG_INFO; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Info(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_INFO, m)
|
||||
return err
|
||||
}
|
||||
|
||||
// Debug logs a message with severity LOG_DEBUG; this overrides the default
|
||||
// priority passed to `srslog.New` and the `srslog.Dial*` functions.
|
||||
func (w *Writer) Debug(m string) (err error) {
|
||||
_, err = w.writeAndRetry(LOG_DEBUG, m)
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *Writer) writeAndRetry(p Priority, s string) (int, error) {
|
||||
pr := (w.priority & facilityMask) | (p & severityMask)
|
||||
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
if w.conn != nil {
|
||||
if n, err := w.write(pr, s); err == nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
if err := w.connect(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return w.write(pr, s)
|
||||
}
|
||||
|
||||
// write generates and writes a syslog formatted string. It formats the
|
||||
// message based on the current Formatter and Framer.
|
||||
func (w *Writer) write(p Priority, msg string) (int, error) {
|
||||
// ensure it ends in a \n
|
||||
if !strings.HasSuffix(msg, "\n") {
|
||||
msg += "\n"
|
||||
}
|
||||
|
||||
err := w.conn.writeString(w.framer, w.formatter, p, w.hostname, w.tag, msg)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Note: return the length of the input, not the number of
|
||||
// bytes printed by Fprintf, because this must behave like
|
||||
// an io.Writer.
|
||||
return len(msg), nil
|
||||
}
|
||||
1
vendor/vendor.json
vendored
1
vendor/vendor.json
vendored
@@ -13,7 +13,6 @@
|
||||
{"path":"github.com/NVIDIA/gpu-monitoring-tools/bindings/go/nvml","checksumSHA1":"P8FATSSgpe5A17FyPrGpsX95Xw8=","revision":"86f2a9fac6c5b597dc494420005144b8ef7ec9fb","revisionTime":"2018-08-29T22:20:09Z"},
|
||||
{"path":"github.com/NYTimes/gziphandler","checksumSHA1":"jktW57+vJsziNVPeXMCoujTzdW4=","revision":"97ae7fbaf81620fe97840685304a78a306a39c64","revisionTime":"2017-09-16T00:36:49Z"},
|
||||
{"path":"github.com/Nvveen/Gotty","checksumSHA1":"Aqy8/FoAIidY/DeQ5oTYSZ4YFVc=","revision":"cd527374f1e5bff4938207604a14f2e38a9cf512","revisionTime":"2012-06-04T00:48:16Z"},
|
||||
{"path":"github.com/RackSec/srslog","checksumSHA1":"GkeYcZh0B14rtg15JAVDPVwjNoY=","revision":"259aed10dfa74ea2961eddd1d9847619f6e98837","revisionTime":"2016-01-20T22:33:50Z"},
|
||||
{"path":"github.com/StackExchange/wmi","checksumSHA1":"qtjd74+bErubh+qyv3s+lWmn9wc=","revision":"ea383cf3ba6ec950874b8486cd72356d007c768f","revisionTime":"2017-04-10T19:29:09Z"},
|
||||
{"path":"github.com/agext/levenshtein","checksumSHA1":"jQh1fnoKPKMURvKkpdRjN695nAQ=","revision":"5f10fee965225ac1eecdc234c09daf5cd9e7f7b6","revisionTime":"2017-02-17T06:30:20Z"},
|
||||
{"path":"github.com/apparentlymart/go-textseg/textseg","checksumSHA1":"Ffhtm8iHH7l2ynVVOIGJE3eiuLA=","revision":"b836f5c4d331d1945a2fead7188db25432d73b69","revisionTime":"2017-05-31T20:39:52Z"},
|
||||
|
||||
Reference in New Issue
Block a user