...

Source file src/gitlab.com/tymonx/go-logger/logger/syslog.go

Documentation: gitlab.com/tymonx/go-logger/logger

     1  // Copyright 2020 Tymoteusz Blazejczyk
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package logger
    16  
    17  import (
    18  	"io"
    19  	"net"
    20  	"strconv"
    21  	"time"
    22  )
    23  
    24  // These constants define default values for syslog.
    25  const (
    26  	DefaultSyslogPort    = 514
    27  	DefaultSyslogVersion = 1
    28  	DefaultSyslogNetwork = "udp"
    29  	DefaultSyslogAddress = "localhost"
    30  	DefaultSyslogTimeout = 100 * time.Millisecond
    31  	DefaultSyslogFormat  = "<{syslogPriority}>{syslogVersion} {iso8601} {address} {name} {pid} {id} - " +
    32  		"{file}:{line}:{function}(): {message}"
    33  	DefaultSyslogFacility = 1
    34  )
    35  
    36  // A Syslog represents a log handler object for logging messages to running
    37  // Syslog server.
    38  type Syslog struct {
    39  	port     int
    40  	version  int
    41  	network  string
    42  	address  string
    43  	facility int
    44  	timeout  time.Duration
    45  	stream   *Stream
    46  }
    47  
    48  // NewSyslog creates a new Syslog log handler object.
    49  func NewSyslog() *Syslog {
    50  	s := &Syslog{
    51  		port:     DefaultSyslogPort,
    52  		version:  DefaultSyslogVersion,
    53  		network:  DefaultSyslogNetwork,
    54  		address:  DefaultSyslogAddress,
    55  		facility: DefaultSyslogFacility,
    56  		timeout:  DefaultSyslogTimeout,
    57  		stream:   NewStream(),
    58  	}
    59  
    60  	s.stream.GetFormatter().SetFormat(DefaultSyslogFormat)
    61  	s.stream.SetOpener(s)
    62  
    63  	return s
    64  }
    65  
    66  // Open opens new connection.
    67  func (s *Syslog) Open() (io.WriteCloser, error) {
    68  	address := s.address + ":" + strconv.Itoa(s.port)
    69  
    70  	if s.timeout != 0 {
    71  		return net.DialTimeout(s.network, address, s.timeout)
    72  	}
    73  
    74  	return net.Dial(s.network, address)
    75  }
    76  
    77  // Enable enables log handler.
    78  func (s *Syslog) Enable() Handler {
    79  	return s.stream.Enable()
    80  }
    81  
    82  // Disable disabled log handler.
    83  func (s *Syslog) Disable() Handler {
    84  	return s.stream.Disable()
    85  }
    86  
    87  // IsEnabled returns if log handler is enabled.
    88  func (s *Syslog) IsEnabled() bool {
    89  	return s.stream.IsEnabled()
    90  }
    91  
    92  // SetFormatter sets Formatter.
    93  func (s *Syslog) SetFormatter(formatter *Formatter) Handler {
    94  	return s.stream.SetFormatter(formatter)
    95  }
    96  
    97  // GetFormatter returns Formatter.
    98  func (s *Syslog) GetFormatter() *Formatter {
    99  	return s.stream.GetFormatter()
   100  }
   101  
   102  // SetLevel sets log level.
   103  func (s *Syslog) SetLevel(level int) Handler {
   104  	return s.stream.SetLevel(level)
   105  }
   106  
   107  // SetMinimumLevel sets minimum log level.
   108  func (s *Syslog) SetMinimumLevel(level int) Handler {
   109  	return s.stream.SetMinimumLevel(level)
   110  }
   111  
   112  // GetMinimumLevel returns minimum log level.
   113  func (s *Syslog) GetMinimumLevel() int {
   114  	return s.stream.GetMinimumLevel()
   115  }
   116  
   117  // SetMaximumLevel sets maximum log level.
   118  func (s *Syslog) SetMaximumLevel(level int) Handler {
   119  	return s.stream.SetMaximumLevel(level)
   120  }
   121  
   122  // GetMaximumLevel returns maximum log level.
   123  func (s *Syslog) GetMaximumLevel() int {
   124  	return s.stream.GetMaximumLevel()
   125  }
   126  
   127  // SetLevelRange sets minimum and maximum log level values.
   128  func (s *Syslog) SetLevelRange(min, max int) Handler {
   129  	return s.stream.SetLevelRange(min, max)
   130  }
   131  
   132  // GetLevelRange returns minimum and maximum log level values.
   133  func (s *Syslog) GetLevelRange() (min, max int) {
   134  	return s.stream.GetLevelRange()
   135  }
   136  
   137  // SetPort sets port number that is used to communicate with Syslog server.
   138  func (s *Syslog) SetPort(port int) *Syslog {
   139  	s.stream.Lock()
   140  	defer s.stream.Unlock()
   141  
   142  	if port <= 0 {
   143  		port = DefaultSyslogPort
   144  	}
   145  
   146  	if s.port != port {
   147  		s.port = port
   148  		s.stream.Reopen()
   149  	}
   150  
   151  	return s
   152  }
   153  
   154  // GetPort returns port number that is used to communicate with Syslog server.
   155  func (s *Syslog) GetPort() int {
   156  	s.stream.RLock()
   157  	defer s.stream.RUnlock()
   158  
   159  	return s.port
   160  }
   161  
   162  // SetTimeout sets connection timeout.
   163  func (s *Syslog) SetTimeout(timeout time.Duration) *Syslog {
   164  	s.stream.Lock()
   165  	defer s.stream.Unlock()
   166  
   167  	if s.timeout != timeout {
   168  		s.timeout = timeout
   169  		s.stream.Reopen()
   170  	}
   171  
   172  	return s
   173  }
   174  
   175  // GetTimeout returns connection timeout.
   176  func (s *Syslog) GetTimeout() time.Duration {
   177  	s.stream.RLock()
   178  	defer s.stream.RUnlock()
   179  
   180  	return s.timeout
   181  }
   182  
   183  // SetNetwork sets network type like "udp" or "tcp" that is used to communicate
   184  // with Syslog server.
   185  func (s *Syslog) SetNetwork(network string) *Syslog {
   186  	s.stream.Lock()
   187  	defer s.stream.Unlock()
   188  
   189  	if network == "" {
   190  		network = DefaultSyslogNetwork
   191  	}
   192  
   193  	if s.network != network {
   194  		s.network = network
   195  		s.stream.Reopen()
   196  	}
   197  
   198  	return s
   199  }
   200  
   201  // GetNetwork returns network type like "udp" or "tcp" that is used to
   202  // communicate with Syslog server.
   203  func (s *Syslog) GetNetwork() string {
   204  	s.stream.RLock()
   205  	defer s.stream.RUnlock()
   206  
   207  	return s.network
   208  }
   209  
   210  // SetAddress sets IP address or hostname that is used to communicate with
   211  // Syslog server.
   212  func (s *Syslog) SetAddress(address string) *Syslog {
   213  	s.stream.Lock()
   214  	defer s.stream.Unlock()
   215  
   216  	if address == "" {
   217  		address = DefaultSyslogAddress
   218  	}
   219  
   220  	if s.address != address {
   221  		s.address = address
   222  		s.stream.Reopen()
   223  	}
   224  
   225  	return s
   226  }
   227  
   228  // GetAddress returns IP address or hostname that is used to communicate with
   229  // Syslog server.
   230  func (s *Syslog) GetAddress() string {
   231  	s.stream.RLock()
   232  	defer s.stream.RUnlock()
   233  
   234  	return s.network
   235  }
   236  
   237  // Emit logs messages from Logger to Syslog server.
   238  func (s *Syslog) Emit(record *Record) error {
   239  	s.stream.GetFormatter().AddFuncs(s.getRecordFuncs(record))
   240  
   241  	return s.stream.Emit(record)
   242  }
   243  
   244  // Close closes communication to Syslog server.
   245  func (s *Syslog) Close() error {
   246  	return s.stream.Close()
   247  }
   248  
   249  // setFormatterFuncs sets template functions that are specific for Syslog log
   250  // messages.
   251  func (s *Syslog) getRecordFuncs(record *Record) FormatterFuncs {
   252  	return FormatterFuncs{
   253  		"syslogVersion": func() int {
   254  			return s.version
   255  		},
   256  		"syslogPriority": func() int {
   257  			severities := [8]int{
   258  				FatalLevel,
   259  				AlertLevel,
   260  				CriticalLevel,
   261  				ErrorLevel,
   262  				WarningLevel,
   263  				NoticeLevel,
   264  				InfoLevel,
   265  				DebugLevel,
   266  			}
   267  
   268  			severity := 0
   269  
   270  			for i, level := range severities {
   271  				if level <= record.Level.Value {
   272  					severity = i
   273  					break
   274  				}
   275  			}
   276  
   277  			return ((0x1F & s.facility) << 3) | (0x07 & severity)
   278  		},
   279  	}
   280  }
   281  

View as plain text