forked from instana/go-sensor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwriter.go
92 lines (77 loc) · 2.71 KB
/
writer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// (c) Copyright IBM Corp. 2021
// (c) Copyright Instana Inc. 2020
//go:build go1.11
// +build go1.11
package storage
import (
"context"
"github.com/instana/go-sensor/instrumentation/cloud.google.com/go/internal/tags"
"sync"
"cloud.google.com/go/storage"
"github.com/mier85/go-sensor/instrumentation/cloud.google.com/go/internal"
ot "github.com/opentracing/opentracing-go"
)
// Writer is an instrumented wrapper for cloud.google.com/go/storage.Writer
// that traces calls made to Google Cloud Storage API.
//
// See https://pkg.go.dev/cloud.google.com/go/storage?tab=doc#Writer for further details on wrapped type.
type Writer struct {
*storage.Writer
Bucket string
ctx context.Context
mu sync.Mutex
writeCtx context.Context
}
// Write calls the Write() method of the wrapped cloud.google.com/go/storage.Writer and initiates an exit span.
// Note that this span will be finished only when Close() is called, since writes are performed
// asynchronously and only guaranteed to be finished upon close. Thus each created span represents
// a single object insertion operation regardless of the number of Write() calls before the Writer
// is closed.
//
// See https://pkg.go.dev/cloud.google.com/go/storage?tab=doc#Writer.Write for further details on wrapped method.
func (w *Writer) Write(p []byte) (n int, err error) {
bucket := w.Writer.ObjectAttrs.Bucket
if bucket == "" {
bucket = w.Bucket
}
w.mu.Lock()
if w.writeCtx == nil {
w.writeCtx = internal.StartExitSpan(w.ctx, "gcs", ot.Tags{
tags.GcsOp: "objects.insert",
tags.GcsBucket: bucket,
tags.GcsObject: w.Writer.ObjectAttrs.Name,
})
}
w.mu.Unlock()
return w.Writer.Write(p)
}
// Close closes the underlying cloud.google.com/go/storage.Writer and finalizes current exit span.
//
// See https://pkg.go.dev/cloud.google.com/go/storage?tab=doc#Writer.Close for further details on wrapped method.
func (w *Writer) Close() error {
err := w.Writer.Close()
w.mu.Lock()
if w.writeCtx != nil {
internal.FinishSpan(w.writeCtx, err)
w.writeCtx = nil
}
w.mu.Unlock()
return err
}
// CloseWithError terminates any writes performed by this Writer with an error and finalizes current exit span.
//
// See https://pkg.go.dev/cloud.google.com/go/storage?tab=doc#Writer.CloseWithError for further details on wrapped method.
//
// Deprecated: this method is added for compatibility with the cloud.google.com/go/storage.Writer interface, however
// it is recommended to cancel the write operation using the context passed to NewWriter instead.
func (w *Writer) CloseWithError(err error) error {
defer func() {
w.mu.Lock()
if w.writeCtx != nil {
internal.FinishSpan(w.writeCtx, err)
w.writeCtx = nil
}
w.mu.Unlock()
}()
return w.Writer.CloseWithError(err)
}