1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-08-23 09:52:08 +08:00
Files
kubo/core/corehttp/logs.go
Andrew Gillis 20d9660a64 chore: use go-log/v2 (#10801)
* chore: update to go-log/v2

go-log v2 has been out for quite a while now and it is time to deprecate v1.

Replace all use of go-log with go-log/v2
Makes /api/v0/log/tail useful over HTTP
Updates dependencies that have moved to go-lov/v2
Removes support for ContextWithLoggable as this is not needed for tracing-like functionality
- Replaces: PR #8765
- Closes issue #8753
- Closes issue #9245
- Closes issue #10809

Other fixes:
* update go-ipfs-cmds
* update http logs test
* fix test
* Read/send one line of log data at a time
* Update -log-level docs
2025-05-19 13:04:05 -07:00

70 lines
1.7 KiB
Go

package corehttp
import (
"bufio"
"fmt"
"net"
"net/http"
logging "github.com/ipfs/go-log/v2"
core "github.com/ipfs/kubo/core"
)
func LogOption() ServeOption {
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
mux.HandleFunc("/logs", func(w http.ResponseWriter, r *http.Request) {
// The log data comes from an io.Reader, and we need to constantly
// read from it and then write to the HTTP response.
pipeReader := logging.NewPipeReader()
done := make(chan struct{})
// Close the pipe reader if the request context is canceled. This
// is necessary to avoiding blocking on reading from the pipe
// reader when the client terminates the request.
go func() {
select {
case <-r.Context().Done(): // Client canceled request
case <-n.Context().Done(): // Node shutdown
case <-done: // log reader goroutine exitex
}
pipeReader.Close()
}()
errs := make(chan error, 1)
go func() {
defer close(errs)
defer close(done)
rdr := bufio.NewReader(pipeReader)
for {
// Read a line of log data and send it to the client.
line, err := rdr.ReadString('\n')
if err != nil {
errs <- fmt.Errorf("error reading log message: %s", err)
return
}
_, err = w.Write([]byte(line))
if err != nil {
// Failed to write to client, probably disconnected.
return
}
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
if r.Context().Err() != nil {
return
}
}
}()
log.Info("log API client connected")
err := <-errs
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
return mux, nil
}
}