Created
June 29, 2017 17:22
-
-
Save chuckhacker/b5f2503282002f9e6e6ac9e703b760b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "errors" | |
| "fmt" | |
| "net" | |
| "os" | |
| "strconv" | |
| "strings" | |
| "time" | |
| ) | |
| var logDNAkey string = "<REDACTED>" | |
| const ( | |
| TCP = "tcp" | |
| TCP_TLS = "tcp_tls" | |
| UDP = "udp" | |
| ) | |
| const ( | |
| LOG_LEVEL_EMERG = 0 | |
| LOG_LEVEL_ALERT = 1 | |
| LOG_LEVEL_CRIT = 2 | |
| LOG_LEVEL_ERR = 3 | |
| LOG_LEVEL_WARNING = 4 | |
| LOG_LEVEL_NOTICE = 5 | |
| LOG_LEVEL_INFO = 6 | |
| LOG_LEVEL_DEBUG = 7 | |
| ) | |
| var LOG_DEFAULT_FACILITY int64 = 3 // DAEMON | |
| type Writer struct { | |
| Port int | |
| Network string | |
| Server string | |
| Program string | |
| Conn net.Conn | |
| } | |
| func constructRemoteLogMessage(message, program string) string { | |
| // fmt.Printf("constructRemoteLogMessage: message=%s program=%s\n", message, program) | |
| words := strings.Fields(message) | |
| levelStr := "UNKNOWN" | |
| component := program | |
| logMessage := message | |
| if len(words) >= 3 { | |
| // return message // well that sucks, maybe just try to format it? | |
| component = words[0] | |
| levelStr = words[1] | |
| logMessage = strings.Join(words[2:], " ") | |
| } | |
| levelInt := LOG_LEVEL_INFO | |
| switch levelStr { | |
| case "EMERG": | |
| levelInt = LOG_LEVEL_EMERG | |
| case "ALERT": | |
| levelInt = LOG_LEVEL_ALERT | |
| case "CRIT": | |
| levelInt = LOG_LEVEL_CRIT | |
| case "ERR": | |
| levelInt = LOG_LEVEL_ERR | |
| case "ERRO": | |
| levelInt = LOG_LEVEL_ERR | |
| case "ERROR": | |
| levelInt = LOG_LEVEL_ERR | |
| case "WARNING": | |
| levelInt = LOG_LEVEL_WARNING | |
| case "WARN": // stupider shit has been done before | |
| levelInt = LOG_LEVEL_WARNING | |
| case "NOTICE": | |
| levelInt = LOG_LEVEL_NOTICE | |
| case "INFO": | |
| levelInt = LOG_LEVEL_INFO | |
| case "DEBUG": | |
| levelInt = LOG_LEVEL_DEBUG | |
| default: | |
| // fmt.Println("Unknown log level: " + levelStr) | |
| levelInt = LOG_LEVEL_INFO | |
| // back to the drawing board | |
| component = program | |
| levelStr = "INFO" | |
| logMessage = message | |
| } | |
| levelProduct := int64(levelInt) + LOG_DEFAULT_FACILITY*8 // level + LOG_DEFAULT_FACILITY*8 | |
| levelProductStr := strconv.FormatInt(levelProduct, 10) | |
| pidInt := os.Getpid() | |
| pidStr := strconv.FormatInt(int64(pidInt), 10) | |
| timestamp := time.Now().UTC().Format(time.RFC3339) | |
| hostName, err := os.Hostname() | |
| if err != nil { | |
| hostName = "localhost" | |
| fmt.Println("os.Hostname() error: " + err.Error()) | |
| } | |
| pid := pidStr + " " | |
| msgID := component + " " | |
| var keyStr = "<key:" + logDNAkey + "> " | |
| return keyStr + "<" + levelProductStr + ">1 " + timestamp + " " + hostName + " " + program + " " + pid + msgID + "- " + logMessage + "\n" | |
| } | |
| // TODO: do all of these things asynchronously?! | |
| func (w *Writer) Dial() error { | |
| address := fmt.Sprintf("%s:%d", w.Server, w.Port) | |
| conn, err := net.Dial(TCP, address) | |
| w.Conn = conn | |
| if err != nil { | |
| fmt.Println("TCP dial error: " + err.Error()) | |
| } | |
| if conn == nil { | |
| fmt.Println("TCP connection error") | |
| } | |
| return err | |
| } | |
| // TODO: maybe it makes sense to use UDP instead here... | |
| func (w *Writer) Write(p []byte) (n int, err error) { | |
| logMessage := constructRemoteLogMessage(string(p[:]), w.Program) | |
| if w.Conn != nil { | |
| n, result := w.Conn.Write([]byte(logMessage)) | |
| if result != nil { | |
| fmt.Println("TCP write error: " + result.Error() + ", should re-dial but won't...") | |
| // w.Dial() | |
| } | |
| return n, result | |
| } else { | |
| fmt.Println("TCP connection error, nil Conn, should re-dial but won't...") | |
| // w.Dial() | |
| } | |
| return 0, errors.New("TCP write error") | |
| } | |
| func (w *Writer) HangUp() error { | |
| err := w.Conn.Close() | |
| if err != nil { | |
| fmt.Println("TCP hang up error: " + err.Error()) | |
| } | |
| return err | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment