waveterm/pkg/blocklogger/blocklogger.go

93 lines
2.2 KiB
Go
Raw Normal View History

// Copyright 2025, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
package blocklogger
import (
"context"
"encoding/base64"
"fmt"
"log"
"strings"
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
)
// Buffer size for the output channel
const outputBufferSize = 1000
var outputChan chan wshrpc.CommandControllerAppendOutputData
func InitBlockLogger() {
outputChan = make(chan wshrpc.CommandControllerAppendOutputData, outputBufferSize)
// Start the output runner
go outputRunner()
}
func outputRunner() {
defer log.Printf("blocklogger: outputRunner exiting")
client := wshclient.GetBareRpcClient()
for data := range outputChan {
// Process each output request synchronously, waiting for response
wshclient.ControllerAppendOutputCommand(client, data, nil)
}
}
type logBlockIdContextKeyType struct{}
var logBlockIdContextKey = logBlockIdContextKeyType{}
type logBlockIdData struct {
BlockId string
Verbose bool
}
func ContextWithLogBlockId(ctx context.Context, blockId string, verbose bool) context.Context {
return context.WithValue(ctx, logBlockIdContextKey, &logBlockIdData{BlockId: blockId, Verbose: verbose})
}
func getLogBlockData(ctx context.Context) *logBlockIdData {
if ctx == nil {
return nil
}
dataPtr := ctx.Value(logBlockIdContextKey)
if dataPtr == nil {
return nil
}
return dataPtr.(*logBlockIdData)
}
func queueLogData(data wshrpc.CommandControllerAppendOutputData) {
select {
case outputChan <- data:
default:
}
}
func writeLogf(blockId string, format string, args []any) {
logStr := fmt.Sprintf(format, args...)
logStr = strings.ReplaceAll(logStr, "\n", "\r\n")
data := wshrpc.CommandControllerAppendOutputData{
BlockId: blockId,
Data64: base64.StdEncoding.EncodeToString([]byte(logStr)),
}
queueLogData(data)
}
func Infof(ctx context.Context, format string, args ...any) {
logData := getLogBlockData(ctx)
if logData == nil {
return
}
writeLogf(logData.BlockId, format, args)
}
func Debugf(ctx context.Context, format string, args ...interface{}) {
logData := getLogBlockData(ctx)
if logData == nil || !logData.Verbose {
return
}
writeLogf(logData.BlockId, format, args)
}