basictracer-go原始碼閱讀——SpanRecorder與wire
SpanRecorder
SpanRecorder 介面用於 Span 的儲存,也就是擔任 Collector 和 Storage 的職責。它向廠商開放了自定義實現自己的 Collector 和 Storage 服務或者元件;儲存資料={TraceID, SpanID, Sampled, Baggage};
type SpanRecorder interface {
RecordSpan(span RawSpan)
}
basictracer-go 內部已經實現了一個基於記憶體的 SpanRecorder。SpanRecorder 具體實現賦值是在初始化 globaltracer 時指定的,也即 tracer.options.SpanRecorder 變數值;
基於記憶體的 SpanRecorder 實現:
type InMemorySpanRecorder struct {
sync.RWMutex
spans []RawSpan
}
func NewInMemoryRecorder() *InMemorySpanRecorder {
return new(InMemorySpanRecorder)
}
// 對RawSpan進行收集和儲存工作
func (r *InMemorySpanRecorder) RecordSpan(span RawSpan) {
r.Lock()
defer r.Unlock()
r.spans = append(r.spans, span)
}
// 獲取[]RawSpan的快照,因為瞬時乾淨列表, 只是如果要併發獲取[]RawSpan以及廠商實現不限制記憶體的話,則記憶體猛增。
func (r *InMemorySpanRecorder) GetSpans() []RawSpan {
r.RLock()
defer r.RUnlock()
spans := make([]RawSpan, len(r.spans))
copy(spans, r.spans)
return spans
}
// 存在GetSpans和GetSampledSpans兩種方法,主要是因為:
// Tracer和Span都存在Sampled,之間存在一定的關係
// 1. 當Tracer設定這個tracer需要儘量儲存下來時,Tracer.Sampled=true,不用理會Span.Sampled值
// 2. 當Tracer.Sampled=false時,則可以根據span執行單元情況,選擇是否要進行Span保留;
func (r *InMemorySpanRecorder) GetSampledSpans() []RawSpan {
... // 所以這個是用來保留取樣的Span, 與Tracer無關
}
// 清空[]RawSpan記憶體儲存
func (r *InMemorySpanRecorder) Reset(){
r.Lock()
defer r.Unlock()
r.spans = nil
}
util
主要用來生成隨機數, 賦值給 TraceID 和 SpanID 值;
wire
wire 為 binaryPropagator 網路傳輸的協議資料流,該協議為 google 的 protobuffer,在 grpc 中廣泛使用。
// bp協議資料格式
message TracerState {
fixed64 trace_id = 1;
fixed64 span_id = 2;
bool sampled =3;
map<string, string> baggage_items = 4;
}
該協議的資料格式在《basictracer-go 原始碼閱讀——event&propagation》的 binaryPropagator 中通過 Inject 和 Extract 方法說明過。
同時,TracerState 也實現了 DelegatingCarrier 介面,這個在 accessPropagator 中給廠商開放了自定義實現 Carrier 的資料儲存和轉換;這裡不再贅述了。
參考資料
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- basictracer-go原始碼閱讀二——SpanGo原始碼
- basictracer-go原始碼閱讀——event&propagationGo原始碼
- basictracer-go原始碼閱讀——examples(完結)Go原始碼
- 【原始碼閱讀】AndPermission原始碼閱讀原始碼
- 【原始碼閱讀】Glide原始碼閱讀之with方法(一)原始碼IDE
- 【原始碼閱讀】Glide原始碼閱讀之into方法(三)原始碼IDE
- Appdash原始碼閱讀——Annotations與EventAPP原始碼
- Appdash原始碼閱讀——Recorder與CollectorAPP原始碼
- 【原始碼閱讀】Glide原始碼閱讀之load方法(二)原始碼IDE
- ReactorKit原始碼閱讀React原始碼
- Vollery原始碼閱讀(—)原始碼
- NGINX原始碼閱讀Nginx原始碼
- ThreadLocal原始碼閱讀thread原始碼
- 原始碼閱讀-HashMap原始碼HashMap
- Runtime 原始碼閱讀原始碼
- RunLoop 原始碼閱讀OOP原始碼
- AmplifyImpostors原始碼閱讀原始碼
- stack原始碼閱讀原始碼
- CountDownLatch原始碼閱讀CountDownLatch原始碼
- fuzz原始碼閱讀原始碼
- HashMap 原始碼閱讀HashMap原始碼
- delta原始碼閱讀原始碼
- AQS原始碼閱讀AQS原始碼
- Mux 原始碼閱讀UX原始碼
- ConcurrentHashMap原始碼閱讀HashMap原始碼
- HashMap原始碼閱讀HashMap原始碼
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- JDK原始碼閱讀:String類閱讀筆記JDK原始碼筆記
- JDK原始碼閱讀:Object類閱讀筆記JDK原始碼Object筆記
- 如何閱讀Java原始碼?Java原始碼
- buffer 原始碼包閱讀原始碼
- 使用OpenGrok閱讀原始碼原始碼
- express 原始碼閱讀(全)Express原始碼
- Kingfisher原始碼閱讀(一)原始碼
- 如何閱讀框架原始碼框架原始碼
- 如何閱讀jdk原始碼?JDK原始碼
- ArrayList原始碼閱讀(增)原始碼
- snabbdom 原始碼閱讀分析原始碼