log stuff added
This commit is contained in:
		
							
								
								
									
										8
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.mod
									
									
									
									
									
								
							@@ -1,3 +1,11 @@
 | 
				
			|||||||
module oc-lib
 | 
					module oc-lib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
go 1.22.0
 | 
					go 1.22.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require github.com/rs/zerolog v1.33.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						github.com/mattn/go-colorable v0.1.13 // indirect
 | 
				
			||||||
 | 
						github.com/mattn/go-isatty v0.0.19 // indirect
 | 
				
			||||||
 | 
						golang.org/x/sys v0.12.0 // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
 | 
				
			||||||
 | 
					github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 | 
				
			||||||
 | 
					github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 | 
				
			||||||
 | 
					github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
 | 
				
			||||||
 | 
					github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 | 
				
			||||||
 | 
					github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
 | 
					github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
 | 
				
			||||||
 | 
					github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
 | 
				
			||||||
 | 
					github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
							
								
								
									
										41
									
								
								logger.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								logger.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					package oclib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"oc-lib/logs"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/rs/zerolog"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var logger zerolog.Logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateLogger
 | 
				
			||||||
 | 
					// Create a new logger
 | 
				
			||||||
 | 
					// Parameters:
 | 
				
			||||||
 | 
					// - appname: string : the name of the application using oclib
 | 
				
			||||||
 | 
					// - url: string : the url of a loki logger, console log only if ""
 | 
				
			||||||
 | 
					// Returns:
 | 
				
			||||||
 | 
					// - zerolog.Logger : the logger that will log for the library and the app
 | 
				
			||||||
 | 
					func CreateLogger(appname string, url string) zerolog.Logger {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if url != "" {
 | 
				
			||||||
 | 
							labels := map[string]string{
 | 
				
			||||||
 | 
								"app":      "app",
 | 
				
			||||||
 | 
								"code":     "go",
 | 
				
			||||||
 | 
								"platform": runtime.GOOS,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lokiWriter := logs.NewLokiWriter(url, labels)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							multiWriter := zerolog.MultiLevelWriter(consoleWriter, lokiWriter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							logger = zerolog.New(multiWriter).With().Timestamp().Logger()
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							logger = zerolog.New(os.Stdout).With().Timestamp().Logger()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return logger
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										97
									
								
								logs/lokiwriter.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								logs/lokiwriter.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					package logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LokiWriter struct {
 | 
				
			||||||
 | 
						url        string
 | 
				
			||||||
 | 
						labels     map[string]string
 | 
				
			||||||
 | 
						httpClient *http.Client
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LokiPayload struct {
 | 
				
			||||||
 | 
						Streams []LokiStream `json:"streams"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LokiStream struct {
 | 
				
			||||||
 | 
						Stream map[string]string `json:"stream"`
 | 
				
			||||||
 | 
						Values [][]string        `json:"values"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewLokiWriter(url string, labels map[string]string) *LokiWriter {
 | 
				
			||||||
 | 
						return &LokiWriter{
 | 
				
			||||||
 | 
							url:        url,
 | 
				
			||||||
 | 
							labels:     labels,
 | 
				
			||||||
 | 
							httpClient: &http.Client{},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (w *LokiWriter) Write(p []byte) (n int, err error) {
 | 
				
			||||||
 | 
						// Use zerolog to parse the log level
 | 
				
			||||||
 | 
						var event map[string]interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(p, &event); err != nil {
 | 
				
			||||||
 | 
							return 0, fmt.Errorf("failed to unmarshal log event: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						level := ""
 | 
				
			||||||
 | 
						if l, ok := event["level"].(string); ok {
 | 
				
			||||||
 | 
							level = l
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						message := ""
 | 
				
			||||||
 | 
						if m, ok := event["message"].(string); ok {
 | 
				
			||||||
 | 
							message = m
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add log level to labels
 | 
				
			||||||
 | 
						labels := make(map[string]string)
 | 
				
			||||||
 | 
						for k, v := range w.labels {
 | 
				
			||||||
 | 
							labels[k] = v
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						labels["level"] = level
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Format the timestamp in nanoseconds
 | 
				
			||||||
 | 
						timestamp := fmt.Sprintf("%d000000", time.Now().UnixNano()/int64(time.Millisecond))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream := LokiStream{
 | 
				
			||||||
 | 
							Stream: labels,
 | 
				
			||||||
 | 
							Values: [][]string{
 | 
				
			||||||
 | 
								{timestamp, message},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						payload := LokiPayload{
 | 
				
			||||||
 | 
							Streams: []LokiStream{stream},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						payloadBytes, err := json.Marshal(payload)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, fmt.Errorf("failed to marshal payload: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fmt.Printf("Sending payload to Loki: %s\n", string(payloadBytes))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						req, err := http.NewRequest("POST", w.url, bytes.NewReader(payloadBytes))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, fmt.Errorf("failed to create HTTP request: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						req.Header.Set("Content-Type", "application/json")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp, err := w.httpClient.Do(req)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, fmt.Errorf("failed to send log to Loki: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer resp.Body.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fmt.Printf("Loki response status: %d\n", resp.StatusCode)
 | 
				
			||||||
 | 
						if resp.StatusCode != http.StatusNoContent {
 | 
				
			||||||
 | 
							return 0, fmt.Errorf("received non-204 response from Loki: %d", resp.StatusCode)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return len(p), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user