Skip to content

Commit 76b8fba

Browse files
Extend anonymizer with additional parameters (#2585)
* Extend anonymizer with additional parameters Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Extend anonymizer with additional parameters Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Feedback changes Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Added basic unit tests Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Ran gofmt Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Added license header Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Fix wrong assert library Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Fix error Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Ran make fmt Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Feedbacks Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Feedbacks Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Attempt to increase code coverage Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Attempt to increase code coverage Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> * Ran make fmt Signed-off-by: Ashmita Bohara <ashmita.bohara152@gmail.com> Co-authored-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
1 parent ee3bbee commit 76b8fba

File tree

3 files changed

+240
-10
lines changed

3 files changed

+240
-10
lines changed

cmd/anonymizer/app/anonymizer/anonymizer.go

+62-9
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,14 @@ type mapping struct {
5353
//
5454
// The mapping from original to obfuscated strings is stored in a file and can be reused between runs.
5555
type Anonymizer struct {
56-
mappingFile string
57-
logger *zap.Logger
58-
59-
lock sync.Mutex
60-
mapping mapping
56+
mappingFile string
57+
logger *zap.Logger
58+
lock sync.Mutex
59+
mapping mapping
60+
hashStandardTags bool
61+
hashCustomTags bool
62+
hashLogs bool
63+
hashProcess bool
6164
}
6265

6366
// New creates new Anonymizer. The mappingFile stores the mapping from original to
@@ -136,15 +139,43 @@ func hash(value string) string {
136139
func (a *Anonymizer) AnonymizeSpan(span *model.Span) *uimodel.Span {
137140
service := span.Process.ServiceName
138141
span.OperationName = a.mapOperationName(service, span.OperationName)
139-
span.Tags = filterTags(span.Tags)
140-
span.Logs = nil
142+
143+
outputTags := filterStandardTags(span.Tags)
144+
// when true, the allowedTags are hashed and when false they are preserved as it is
145+
if a.hashStandardTags {
146+
outputTags = hashTags(outputTags)
147+
}
148+
// when true, all tags other than allowedTags are hashed, when false they are dropped
149+
if a.hashCustomTags {
150+
customTags := hashTags(filterCustomTags(span.Tags))
151+
outputTags = append(outputTags, customTags...)
152+
}
153+
span.Tags = outputTags
154+
155+
// when true, logs are hashed, when false, they are dropped
156+
if a.hashLogs {
157+
for _, log := range span.Logs {
158+
log.Fields = hashTags(log.Fields)
159+
}
160+
} else {
161+
span.Logs = nil
162+
}
163+
141164
span.Process.ServiceName = a.mapServiceName(service)
142-
span.Process.Tags = nil
165+
166+
// when true, process tags are hashed, when false they are dropped
167+
if a.hashProcess {
168+
span.Process.Tags = hashTags(span.Process.Tags)
169+
} else {
170+
span.Process.Tags = nil
171+
}
172+
143173
span.Warnings = nil
144174
return uiconv.FromDomainEmbedProcess(span)
145175
}
146176

147-
func filterTags(tags []model.KeyValue) []model.KeyValue {
177+
// filterStandardTags returns only allowedTags
178+
func filterStandardTags(tags []model.KeyValue) []model.KeyValue {
148179
out := make([]model.KeyValue, 0, len(tags))
149180
for _, tag := range tags {
150181
if !allowedTags[tag.Key] {
@@ -166,3 +197,25 @@ func filterTags(tags []model.KeyValue) []model.KeyValue {
166197
}
167198
return out
168199
}
200+
201+
// filterCustomTags returns all tags other than allowedTags
202+
func filterCustomTags(tags []model.KeyValue) []model.KeyValue {
203+
out := make([]model.KeyValue, 0, len(tags))
204+
for _, tag := range tags {
205+
if !allowedTags[tag.Key] {
206+
out = append(out, tag)
207+
}
208+
}
209+
return out
210+
}
211+
212+
// hashTags converts each tag into corresponding string values
213+
// and then find its hash
214+
func hashTags(tags []model.KeyValue) []model.KeyValue {
215+
out := make([]model.KeyValue, 0, len(tags))
216+
for _, tag := range tags {
217+
kv := model.String(hash(tag.Key), hash(tag.AsString()))
218+
out = append(out, kv)
219+
}
220+
return out
221+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Copyright (c) 2020 The Jaeger Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package anonymizer
16+
17+
import (
18+
"testing"
19+
"time"
20+
21+
"github.com/stretchr/testify/assert"
22+
23+
"github.com/jaegertracing/jaeger/model"
24+
)
25+
26+
var tags = []model.KeyValue{
27+
model.Bool("error", true),
28+
model.String("http.method", "POST"),
29+
model.Bool("foobar", true),
30+
}
31+
32+
var traceID = model.NewTraceID(1, 2)
33+
34+
var span1 = &model.Span{
35+
TraceID: traceID,
36+
SpanID: model.NewSpanID(1),
37+
Process: &model.Process{
38+
ServiceName: "serviceName",
39+
Tags: tags,
40+
},
41+
OperationName: "operationName",
42+
Tags: tags,
43+
Logs: []model.Log{
44+
{
45+
Timestamp: time.Now(),
46+
Fields: []model.KeyValue{
47+
model.String("logKey", "logValue"),
48+
},
49+
},
50+
},
51+
Duration: time.Second * 5,
52+
StartTime: time.Unix(300, 0),
53+
}
54+
55+
var span2 = &model.Span{
56+
TraceID: traceID,
57+
SpanID: model.NewSpanID(1),
58+
Process: &model.Process{
59+
ServiceName: "serviceName",
60+
Tags: tags,
61+
},
62+
OperationName: "operationName",
63+
Tags: tags,
64+
Logs: []model.Log{
65+
{
66+
Timestamp: time.Now(),
67+
Fields: []model.KeyValue{
68+
model.String("logKey", "logValue"),
69+
},
70+
},
71+
},
72+
Duration: time.Second * 5,
73+
StartTime: time.Unix(300, 0),
74+
}
75+
76+
func TestAnonymizer_FilterStandardTags(t *testing.T) {
77+
expected := []model.KeyValue{
78+
model.Bool("error", true),
79+
model.String("http.method", "POST"),
80+
}
81+
actual := filterStandardTags(tags)
82+
assert.Equal(t, expected, actual)
83+
}
84+
85+
func TestAnonymizer_FilterCustomTags(t *testing.T) {
86+
expected := []model.KeyValue{
87+
model.Bool("foobar", true),
88+
}
89+
actual := filterCustomTags(tags)
90+
assert.Equal(t, expected, actual)
91+
}
92+
93+
func TestAnonymizer_Hash(t *testing.T) {
94+
data := "foobar"
95+
expected := "340d8765a4dda9c2"
96+
actual := hash(data)
97+
assert.Equal(t, actual, expected)
98+
}
99+
100+
func TestAnonymizer_AnonymizeSpan_AllTrue(t *testing.T) {
101+
anonymizer := &Anonymizer{
102+
mapping: mapping{
103+
Services: make(map[string]string),
104+
Operations: make(map[string]string),
105+
},
106+
hashStandardTags: true,
107+
hashCustomTags: true,
108+
hashProcess: true,
109+
hashLogs: true,
110+
}
111+
_ = anonymizer.AnonymizeSpan(span1)
112+
assert.Equal(t, 3, len(span1.Tags))
113+
assert.Equal(t, 1, len(span1.Logs))
114+
assert.Equal(t, 3, len(span1.Process.Tags))
115+
}
116+
117+
func TestAnonymizer_AnonymizeSpan_AllFalse(t *testing.T) {
118+
anonymizer := &Anonymizer{
119+
mapping: mapping{
120+
Services: make(map[string]string),
121+
Operations: make(map[string]string),
122+
},
123+
hashStandardTags: false,
124+
hashCustomTags: false,
125+
hashProcess: false,
126+
hashLogs: false,
127+
}
128+
_ = anonymizer.AnonymizeSpan(span2)
129+
assert.Equal(t, 2, len(span2.Tags))
130+
assert.Equal(t, 0, len(span2.Logs))
131+
assert.Equal(t, 0, len(span2.Process.Tags))
132+
}
133+
134+
func TestAnonymizer_MapString_Present(t *testing.T) {
135+
v := "foobar"
136+
m := map[string]string{
137+
"foobar": "hashed_foobar",
138+
}
139+
anonymizer := &Anonymizer{}
140+
actual := anonymizer.mapString(v, m)
141+
assert.Equal(t, "hashed_foobar", actual)
142+
}
143+
144+
func TestAnonymizer_MapString_Absent(t *testing.T) {
145+
v := "foobar"
146+
m := map[string]string{}
147+
anonymizer := &Anonymizer{}
148+
actual := anonymizer.mapString(v, m)
149+
assert.Equal(t, "340d8765a4dda9c2", actual)
150+
}
151+
152+
func TestAnonymizer_MapServiceName(t *testing.T) {
153+
anonymizer := &Anonymizer{
154+
mapping: mapping{
155+
Services: map[string]string{
156+
"api": "hashed_api",
157+
},
158+
},
159+
}
160+
actual := anonymizer.mapServiceName("api")
161+
assert.Equal(t, "hashed_api", actual)
162+
}
163+
164+
func TestAnonymizer_MapOperationName(t *testing.T) {
165+
anonymizer := &Anonymizer{
166+
mapping: mapping{
167+
Services: map[string]string{
168+
"api": "hashed_api",
169+
},
170+
Operations: map[string]string{
171+
"[api]:delete": "hashed_api_delete",
172+
},
173+
},
174+
}
175+
actual := anonymizer.mapOperationName("api", "delete")
176+
assert.Equal(t, "hashed_api_delete", actual)
177+
}

plugin/sampling/strategystore/static/strategy_store_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func strategiesJSON(probability float32) string {
5656
"param": 5
5757
}
5858
]
59-
}
59+
}
6060
`,
6161
probability,
6262
)

0 commit comments

Comments
 (0)