github.com/smithx10/nomad@v0.9.1-rc1/client/logmon/logging/syslog_server.go (about)

     1  package logging
     2  
     3  import (
     4  	"bufio"
     5  	"net"
     6  	"sync"
     7  
     8  	hclog "github.com/hashicorp/go-hclog"
     9  )
    10  
    11  // SyslogServer is a server which listens to syslog messages and parses them
    12  type SyslogServer struct {
    13  	listener net.Listener
    14  	messages chan *SyslogMessage
    15  	parser   *DockerLogParser
    16  
    17  	doneCh   chan interface{}
    18  	done     bool
    19  	doneLock sync.Mutex
    20  
    21  	logger hclog.Logger
    22  }
    23  
    24  // NewSyslogServer creates a new syslog server
    25  func NewSyslogServer(l net.Listener, messages chan *SyslogMessage, logger hclog.Logger) *SyslogServer {
    26  	logger = logger.Named("logcollector.server")
    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  			return
    43  		default:
    44  			connection, err := s.listener.Accept()
    45  			if err != nil {
    46  				s.doneLock.Lock()
    47  				done := s.done
    48  				s.doneLock.Unlock()
    49  				if done {
    50  					return
    51  				}
    52  
    53  				s.logger.Error("error in accepting connection", "err", err)
    54  				continue
    55  			}
    56  			go s.read(connection)
    57  		}
    58  	}
    59  }
    60  
    61  // read reads the bytes from a connection
    62  func (s *SyslogServer) read(connection net.Conn) {
    63  	defer connection.Close()
    64  	scanner := bufio.NewScanner(bufio.NewReader(connection))
    65  
    66  	for {
    67  		select {
    68  		case <-s.doneCh:
    69  			return
    70  		default:
    71  		}
    72  		if scanner.Scan() {
    73  			b := scanner.Bytes()
    74  			msg := s.parser.Parse(b)
    75  			s.messages <- msg
    76  		} else {
    77  			return
    78  		}
    79  	}
    80  }
    81  
    82  // Shutdown the syslog server
    83  func (s *SyslogServer) Shutdown() {
    84  	s.doneLock.Lock()
    85  	defer s.doneLock.Unlock()
    86  
    87  	if !s.done {
    88  		close(s.doneCh)
    89  		close(s.messages)
    90  		s.done = true
    91  		s.listener.Close()
    92  	}
    93  }