This commit is contained in:
		@@ -5,8 +5,10 @@ import (
 | 
				
			|||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"strings"
 | 
						"os"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/rs/zerolog"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LokiWriter struct {
 | 
					type LokiWriter struct {
 | 
				
			||||||
@@ -20,13 +22,8 @@ type LokiPayload struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LokiStream struct {
 | 
					type LokiStream struct {
 | 
				
			||||||
	Labels  string      `json:"labels"`
 | 
						Stream map[string]string `json:"stream"`
 | 
				
			||||||
	Entries []LokiEntry `json:"entries"`
 | 
						Values [][]string        `json:"values"`
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LokiEntry struct {
 | 
					 | 
				
			||||||
	Timestamp string `json:"ts"`
 | 
					 | 
				
			||||||
	Line      string `json:"line"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewLokiWriter(url string, labels map[string]string) *LokiWriter {
 | 
					func NewLokiWriter(url string, labels map[string]string) *LokiWriter {
 | 
				
			||||||
@@ -38,21 +35,37 @@ func NewLokiWriter(url string, labels map[string]string) *LokiWriter {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (w *LokiWriter) Write(p []byte) (n int, err error) {
 | 
					func (w *LokiWriter) Write(p []byte) (n int, err error) {
 | 
				
			||||||
	// Format log entry for Loki
 | 
						// Use zerolog to parse the log level
 | 
				
			||||||
	entry := LokiEntry{
 | 
						var event map[string]interface{}
 | 
				
			||||||
		Timestamp: time.Now().Format(time.RFC3339Nano),
 | 
						if err := json.Unmarshal(p, &event); err != nil {
 | 
				
			||||||
		Line:      string(p),
 | 
							return 0, fmt.Errorf("failed to unmarshal log event: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	labels := []string{}
 | 
						level := ""
 | 
				
			||||||
	for k, v := range w.labels {
 | 
						if l, ok := event["level"].(string); ok {
 | 
				
			||||||
		labels = append(labels, fmt.Sprintf(`%s="%s"`, k, v))
 | 
							level = l
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	labelString := "{" + strings.Join(labels, ",") + "}"
 | 
					
 | 
				
			||||||
 | 
						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 := LokiStream{
 | 
				
			||||||
		Labels:  labelString,
 | 
							Stream: labels,
 | 
				
			||||||
		Entries: []LokiEntry{entry},
 | 
							Values: [][]string{
 | 
				
			||||||
 | 
								{timestamp, message},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	payload := LokiPayload{
 | 
						payload := LokiPayload{
 | 
				
			||||||
@@ -64,6 +77,8 @@ func (w *LokiWriter) Write(p []byte) (n int, err error) {
 | 
				
			|||||||
		return 0, fmt.Errorf("failed to marshal payload: %w", err)
 | 
							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))
 | 
						req, err := http.NewRequest("POST", w.url, bytes.NewReader(payloadBytes))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return 0, fmt.Errorf("failed to create HTTP request: %w", err)
 | 
							return 0, fmt.Errorf("failed to create HTTP request: %w", err)
 | 
				
			||||||
@@ -76,9 +91,32 @@ func (w *LokiWriter) Write(p []byte) (n int, err error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	defer resp.Body.Close()
 | 
						defer resp.Body.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fmt.Printf("Loki response status: %d\n", resp.StatusCode)
 | 
				
			||||||
	if resp.StatusCode != http.StatusNoContent {
 | 
						if resp.StatusCode != http.StatusNoContent {
 | 
				
			||||||
		return 0, fmt.Errorf("received non-204 response from Loki: %d", resp.StatusCode)
 | 
							return 0, fmt.Errorf("received non-204 response from Loki: %d", resp.StatusCode)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return len(p), nil
 | 
						return len(p), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
						lokiURL := "http://your-loki-url/loki/api/v1/push"
 | 
				
			||||||
 | 
						labels := map[string]string{
 | 
				
			||||||
 | 
							"app": "your_app_name",
 | 
				
			||||||
 | 
							// Add more labels as needed
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						lokiWriter := NewLokiWriter(lokiURL, labels)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						multiWriter := zerolog.MultiLevelWriter(consoleWriter, lokiWriter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger := zerolog.New(multiWriter).With().Timestamp().Logger()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Configure the logger in the sublibrary
 | 
				
			||||||
 | 
						sublibrary.AddLogger(logger)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						logger.Info().Msg("Main library log message")
 | 
				
			||||||
 | 
						sublibrary.SublibraryFunction()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user