github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/driver/logging/syslog_server_unix.go (about)

     1  // +build !windows
     2  
     3  package logging
     4  
     5  import (
     6  	"bufio"
     7  	"log"
     8  	"net"
     9  	"sync"
    10  )
    11  
    12  // SyslogServer is a server which listens to syslog messages and parses them
    13  type SyslogServer struct {
    14  	listener net.Listener
    15  	messages chan *SyslogMessage
    16  	parser   *DockerLogParser
    17  
    18  	doneCh   chan interface{}
    19  	done     bool
    20  	doneLock sync.Mutex
    21  
    22  	logger *log.Logger
    23  }
    24  
    25  // NewSyslogServer creates a new syslog server
    26  func NewSyslogServer(l net.Listener, messages chan *SyslogMessage, logger *log.Logger) *SyslogServer {
    27  	parser := NewDockerLogParser(logger)
    28  	return &SyslogServer{
    29  		listener: l,
    30  		messages: messages,
    31  		parser:   parser,
    32  		logger:   logger,
    33  		doneCh:   make(chan interface{}),
    34  	}
    35  }
    36  
    37  // Start starts accepting syslog connections
    38  func (s *SyslogServer) Start() {
    39  	for {
    40  		select {
    41  		case <-s.doneCh:
    42  			s.listener.Close()
    43  			return
    44  		default:
    45  			connection, err := s.listener.Accept()
    46  			if err != nil {
    47  				s.logger.Printf("[ERR] logcollector.server: error in accepting connection: %v", err)
    48  				continue
    49  			}
    50  			go s.read(connection)
    51  		}
    52  	}
    53  }
    54  
    55  // read reads the bytes from a connection
    56  func (s *SyslogServer) read(connection net.Conn) {
    57  	defer connection.Close()
    58  	scanner := bufio.NewScanner(bufio.NewReader(connection))
    59  
    60  	for {
    61  		select {
    62  		case <-s.doneCh:
    63  			return
    64  		default:
    65  		}
    66  		if scanner.Scan() {
    67  			b := scanner.Bytes()
    68  			msg := s.parser.Parse(b)
    69  			s.messages <- msg
    70  		} else {
    71  			return
    72  		}
    73  	}
    74  }
    75  
    76  // Shutdown shutsdown the syslog server
    77  func (s *SyslogServer) Shutdown() {
    78  	s.doneLock.Lock()
    79  	s.doneLock.Unlock()
    80  
    81  	if !s.done {
    82  		close(s.doneCh)
    83  		close(s.messages)
    84  		s.done = true
    85  	}
    86  }