logs_exporter_test.go 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. package datasetexporter
  4. import (
  5. "bytes"
  6. "compress/gzip"
  7. "context"
  8. "encoding/json"
  9. "io"
  10. "net/http"
  11. "net/http/httptest"
  12. "sort"
  13. "strconv"
  14. "sync"
  15. "sync/atomic"
  16. "testing"
  17. "time"
  18. "github.com/scalyr/dataset-go/pkg/api/add_events"
  19. "github.com/scalyr/dataset-go/pkg/api/request"
  20. "github.com/stretchr/testify/assert"
  21. "go.opentelemetry.io/collector/component/componenttest"
  22. "go.opentelemetry.io/collector/exporter/exporterhelper"
  23. "go.opentelemetry.io/collector/exporter/exportertest"
  24. "go.opentelemetry.io/collector/pdata/pcommon"
  25. "go.opentelemetry.io/collector/pdata/plog"
  26. "github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal/testdata"
  27. )
  28. func TestCreateLogsExporter(t *testing.T) {
  29. ctx := context.Background()
  30. createSettings := exportertest.NewNopCreateSettings()
  31. tests := createExporterTests()
  32. for _, tt := range tests {
  33. t.Run(tt.name, func(*testing.T) {
  34. logs, err := createLogsExporter(ctx, createSettings, tt.config)
  35. if err == nil {
  36. assert.Nil(t, tt.expectedError, tt.name)
  37. assert.NotNil(t, logs, tt.name)
  38. } else {
  39. if tt.expectedError == nil {
  40. assert.Nil(t, err, tt.name)
  41. } else {
  42. assert.Equal(t, tt.expectedError.Error(), err.Error(), tt.name)
  43. assert.Nil(t, logs, tt.name)
  44. }
  45. }
  46. })
  47. }
  48. }
  49. func TestBuildBody(t *testing.T) {
  50. slice := pcommon.NewValueSlice()
  51. err := slice.FromRaw([]any{1, 2, 3})
  52. assert.NoError(t, err)
  53. bytes := pcommon.NewValueBytes()
  54. err = bytes.FromRaw([]byte{byte(65), byte(66), byte(67)})
  55. assert.NoError(t, err)
  56. tests := []struct {
  57. body pcommon.Value
  58. valueType string
  59. message string
  60. }{
  61. {
  62. body: pcommon.NewValueEmpty(),
  63. valueType: "empty",
  64. message: "",
  65. },
  66. {
  67. body: pcommon.NewValueStr("foo"),
  68. valueType: "string",
  69. message: "foo",
  70. },
  71. {
  72. body: pcommon.NewValueBool(true),
  73. valueType: "bool",
  74. message: "true",
  75. },
  76. {
  77. body: pcommon.NewValueDouble(42.5),
  78. valueType: "double",
  79. message: "42.5",
  80. },
  81. {
  82. body: pcommon.NewValueInt(42),
  83. valueType: "int",
  84. message: "42",
  85. },
  86. {
  87. body: bytes,
  88. valueType: "bytes",
  89. message: "QUJD",
  90. },
  91. {
  92. body: slice,
  93. valueType: "simpleMap",
  94. message: "[1,2,3]",
  95. },
  96. }
  97. settings := newDefaultLogsSettings()
  98. for _, tt := range tests {
  99. t.Run(tt.valueType, func(*testing.T) {
  100. attrs := make(map[string]any)
  101. msg := buildBody(settings, attrs, tt.body)
  102. assert.Equal(t, tt.message, msg, tt.valueType)
  103. })
  104. }
  105. }
  106. func TestBuildBodyMap(t *testing.T) {
  107. m := pcommon.NewValueMap()
  108. err := m.FromRaw(map[string]any{
  109. "scalar": "scalar-value",
  110. "map": map[string]any{
  111. "m1": "v1",
  112. "m2": "v2",
  113. },
  114. "array": []any{1, 2, 3},
  115. })
  116. if assert.NoError(t, err) {
  117. settings := newDefaultLogsSettings()
  118. settings.DecomposeComplexMessageField = true
  119. attrs := make(map[string]any)
  120. msg := buildBody(settings, attrs, m)
  121. expectedAttrs := make(map[string]any)
  122. expectedAttrs["body.map.scalar"] = "scalar-value"
  123. expectedAttrs["body.map.map.m1"] = "v1"
  124. expectedAttrs["body.map.map.m2"] = "v2"
  125. expectedAttrs["body.map.array.0"] = int64(1)
  126. expectedAttrs["body.map.array.1"] = int64(2)
  127. expectedAttrs["body.map.array.2"] = int64(3)
  128. expectedMsg := "{\"array\":[1,2,3],\"map\":{\"m1\":\"v1\",\"m2\":\"v2\"},\"scalar\":\"scalar-value\"}"
  129. assert.Equal(t, expectedMsg, msg)
  130. assert.Equal(t, expectedAttrs, attrs)
  131. }
  132. }
  133. var testLThread = &add_events.Thread{
  134. Id: "TL",
  135. Name: "logs",
  136. }
  137. var testLLog = &add_events.Log{
  138. Id: "LL",
  139. Attrs: map[string]any{},
  140. }
  141. var testServerHost = "foo"
  142. var testLEventRaw = &add_events.Event{
  143. Thread: testLThread.Id,
  144. Log: testLLog.Id,
  145. Sev: 3,
  146. Ts: "1581452773000000789",
  147. ServerHost: testServerHost,
  148. Attrs: map[string]any{
  149. "app": "server",
  150. "instance_num": int64(1),
  151. "dropped_attributes_count": uint32(1),
  152. "message": "This is a log message",
  153. "span_id": "0102040800000000",
  154. "trace_id": "08040201000000000000000000000000",
  155. },
  156. }
  157. var testLEventRawWithScopeInfo = &add_events.Event{
  158. Thread: testLThread.Id,
  159. Log: testLLog.Id,
  160. Sev: 3,
  161. Ts: "1581452773000000789",
  162. ServerHost: testServerHost,
  163. Attrs: map[string]any{
  164. "app": "server",
  165. "instance_num": int64(1),
  166. "dropped_attributes_count": uint32(1),
  167. "scope.name": "test-scope",
  168. "message": "This is a log message",
  169. "span_id": "0102040800000000",
  170. "trace_id": "08040201000000000000000000000000",
  171. },
  172. }
  173. var testLEventReq = &add_events.Event{
  174. Thread: testLEventRaw.Thread,
  175. Log: testLEventRaw.Log,
  176. Sev: testLEventRaw.Sev,
  177. Ts: testLEventRaw.Ts,
  178. Attrs: map[string]any{
  179. add_events.AttrOrigServerHost: testServerHost,
  180. "app": "server",
  181. "instance_num": float64(1),
  182. "dropped_attributes_count": float64(1),
  183. "message": "This is a log message",
  184. "span_id": "0102040800000000",
  185. "trace_id": "08040201000000000000000000000000",
  186. "bundle_key": "d41d8cd98f00b204e9800998ecf8427e",
  187. },
  188. }
  189. func TestBuildEventFromLog(t *testing.T) {
  190. tests := []struct {
  191. name string
  192. settings LogsSettings
  193. complexBody bool
  194. includeSpanID bool
  195. expected add_events.EventAttrs
  196. }{
  197. {
  198. name: "DefaultSimpleBody",
  199. settings: newDefaultLogsSettings(),
  200. complexBody: false,
  201. includeSpanID: false,
  202. expected: add_events.EventAttrs{
  203. "message": "This is a log message",
  204. "string": "stringA",
  205. "map.map_empty": nil,
  206. "map.map_string": "map_stringA",
  207. "map.map_map.map_map_string": "map_map_stringA",
  208. "slice.0": "slice_stringA",
  209. "name": "filled_nameA",
  210. "span_id": "filled_span_idA",
  211. "scope.attributes.string": "stringS",
  212. "scope.attributes.map.map_empty": nil,
  213. "scope.attributes.map.map_string": "map_stringS",
  214. "scope.attributes.map.map_map.map_map_string": "map_map_stringS",
  215. "scope.attributes.slice.0": "slice_stringS",
  216. "scope.attributes.name": "filled_nameS",
  217. "scope.attributes.span_id": "filled_span_idS",
  218. },
  219. },
  220. {
  221. name: "DefaultComplexBody",
  222. settings: newDefaultLogsSettings(),
  223. complexBody: true,
  224. includeSpanID: false,
  225. expected: add_events.EventAttrs{
  226. "message": "{\"empty_map\":{},\"empty_slice\":[],\"map\":{\"map_empty\":null,\"map_map\":{\"map_map_string\":\"map_map_stringM\"},\"map_string\":\"map_stringM\"},\"name\":\"filled_nameM\",\"slice\":[\"slice_stringM\"],\"span_id\":\"filled_span_idM\",\"string\":\"stringM\"}",
  227. "string": "stringA",
  228. "map.map_empty": nil,
  229. "map.map_string": "map_stringA",
  230. "map.map_map.map_map_string": "map_map_stringA",
  231. "slice.0": "slice_stringA",
  232. "name": "filled_nameA",
  233. "span_id": "filled_span_idA",
  234. "scope.attributes.string": "stringS",
  235. "scope.attributes.map.map_empty": nil,
  236. "scope.attributes.map.map_string": "map_stringS",
  237. "scope.attributes.map.map_map.map_map_string": "map_map_stringS",
  238. "scope.attributes.slice.0": "slice_stringS",
  239. "scope.attributes.name": "filled_nameS",
  240. "scope.attributes.span_id": "filled_span_idS",
  241. },
  242. },
  243. {
  244. name: "DefaultComplexBodyWithSpanID",
  245. settings: newDefaultLogsSettings(),
  246. complexBody: true,
  247. includeSpanID: true,
  248. expected: add_events.EventAttrs{
  249. "message": "{\"empty_map\":{},\"empty_slice\":[],\"map\":{\"map_empty\":null,\"map_map\":{\"map_map_string\":\"map_map_stringM\"},\"map_string\":\"map_stringM\"},\"name\":\"filled_nameM\",\"slice\":[\"slice_stringM\"],\"span_id\":\"filled_span_idM\",\"string\":\"stringM\"}",
  250. "span_id": "0101010101010101",
  251. "string": "stringA",
  252. "map.map_empty": nil,
  253. "map.map_string": "map_stringA",
  254. "map.map_map.map_map_string": "map_map_stringA",
  255. "slice.0": "slice_stringA",
  256. "name": "filled_nameA",
  257. "span_id_": "filled_span_idA",
  258. "scope.attributes.string": "stringS",
  259. "scope.attributes.map.map_empty": nil,
  260. "scope.attributes.map.map_string": "map_stringS",
  261. "scope.attributes.map.map_map.map_map_string": "map_map_stringS",
  262. "scope.attributes.slice.0": "slice_stringS",
  263. "scope.attributes.name": "filled_nameS",
  264. "scope.attributes.span_id": "filled_span_idS",
  265. },
  266. },
  267. {
  268. name: "FullSimpleBody",
  269. complexBody: false,
  270. includeSpanID: false,
  271. settings: LogsSettings{
  272. ExportResourceInfo: true,
  273. ExportResourcePrefix: "__R__",
  274. ExportScopeInfo: true,
  275. ExportScopePrefix: "__S__",
  276. exportSettings: exportSettings{
  277. ExportSeparator: ".SEP.",
  278. ExportDistinguishingSuffix: ".SUF.",
  279. },
  280. DecomposeComplexMessageField: true,
  281. DecomposedComplexMessagePrefix: "__M__",
  282. },
  283. expected: add_events.EventAttrs{
  284. "message": "This is a log message",
  285. "string": "stringA",
  286. "map.SEP.map_empty": nil,
  287. "map.SEP.map_string": "map_stringA",
  288. "map.SEP.map_map.SEP.map_map_string": "map_map_stringA",
  289. "slice.SEP.0": "slice_stringA",
  290. "name": "filled_nameA",
  291. "span_id": "filled_span_idA",
  292. "__S__string": "stringS",
  293. "__S__map.SEP.map_empty": nil,
  294. "__S__map.SEP.map_string": "map_stringS",
  295. "__S__map.SEP.map_map.SEP.map_map_string": "map_map_stringS",
  296. "__S__slice.SEP.0": "slice_stringS",
  297. "__S__name": "filled_nameS",
  298. "__S__span_id": "filled_span_idS",
  299. "__R__string": "stringR",
  300. "__R__map.SEP.map_empty": nil,
  301. "__R__map.SEP.map_string": "map_stringR",
  302. "__R__map.SEP.map_map.SEP.map_map_string": "map_map_stringR",
  303. "__R__slice.SEP.0": "slice_stringR",
  304. "__R__name": "filled_nameR",
  305. "__R__span_id": "filled_span_idR",
  306. "__R__resource-attr": "resource-attr-val-1",
  307. },
  308. },
  309. {
  310. name: "FullComplexBody",
  311. complexBody: true,
  312. includeSpanID: false,
  313. settings: LogsSettings{
  314. ExportResourceInfo: true,
  315. ExportResourcePrefix: "__R__",
  316. ExportScopeInfo: true,
  317. ExportScopePrefix: "__S__",
  318. exportSettings: exportSettings{
  319. ExportSeparator: ".SEP.",
  320. ExportDistinguishingSuffix: ".SUF.",
  321. },
  322. DecomposeComplexMessageField: true,
  323. DecomposedComplexMessagePrefix: "__M__",
  324. },
  325. expected: add_events.EventAttrs{
  326. "message": "{\"empty_map\":{},\"empty_slice\":[],\"map\":{\"map_empty\":null,\"map_map\":{\"map_map_string\":\"map_map_stringM\"},\"map_string\":\"map_stringM\"},\"name\":\"filled_nameM\",\"slice\":[\"slice_stringM\"],\"span_id\":\"filled_span_idM\",\"string\":\"stringM\"}",
  327. "__M__string": "stringM",
  328. "__M__map.SEP.map_empty": nil,
  329. "__M__map.SEP.map_string": "map_stringM",
  330. "__M__map.SEP.map_map.SEP.map_map_string": "map_map_stringM",
  331. "__M__slice.SEP.0": "slice_stringM",
  332. "__M__name": "filled_nameM",
  333. "__M__span_id": "filled_span_idM",
  334. "string": "stringA",
  335. "map.SEP.map_empty": nil,
  336. "map.SEP.map_string": "map_stringA",
  337. "map.SEP.map_map.SEP.map_map_string": "map_map_stringA",
  338. "slice.SEP.0": "slice_stringA",
  339. "name": "filled_nameA",
  340. "span_id": "filled_span_idA",
  341. "__S__string": "stringS",
  342. "__S__map.SEP.map_empty": nil,
  343. "__S__map.SEP.map_string": "map_stringS",
  344. "__S__map.SEP.map_map.SEP.map_map_string": "map_map_stringS",
  345. "__S__slice.SEP.0": "slice_stringS",
  346. "__S__name": "filled_nameS",
  347. "__S__span_id": "filled_span_idS",
  348. "__R__string": "stringR",
  349. "__R__map.SEP.map_empty": nil,
  350. "__R__map.SEP.map_string": "map_stringR",
  351. "__R__map.SEP.map_map.SEP.map_map_string": "map_map_stringR",
  352. "__R__slice.SEP.0": "slice_stringR",
  353. "__R__name": "filled_nameR",
  354. "__R__span_id": "filled_span_idR",
  355. "__R__resource-attr": "resource-attr-val-1",
  356. },
  357. },
  358. {
  359. name: "Minimal",
  360. complexBody: false,
  361. includeSpanID: false,
  362. settings: LogsSettings{
  363. ExportResourceInfo: false,
  364. ExportResourcePrefix: "__R__",
  365. ExportScopeInfo: false,
  366. ExportScopePrefix: "__S__",
  367. exportSettings: exportSettings{
  368. ExportSeparator: ".SEP.",
  369. ExportDistinguishingSuffix: ".SUF.",
  370. },
  371. DecomposeComplexMessageField: false,
  372. },
  373. expected: add_events.EventAttrs{
  374. "message": "This is a log message",
  375. "string": "stringA",
  376. "map.SEP.map_empty": nil,
  377. "map.SEP.map_string": "map_stringA",
  378. "map.SEP.map_map.SEP.map_map_string": "map_map_stringA",
  379. "slice.SEP.0": "slice_stringA",
  380. "name": "filled_nameA",
  381. "span_id": "filled_span_idA",
  382. },
  383. },
  384. {
  385. name: "EmptyPrefixesAndNonEmptySuffixSimpleBody",
  386. complexBody: false,
  387. includeSpanID: false,
  388. settings: LogsSettings{
  389. ExportResourceInfo: true,
  390. ExportResourcePrefix: "",
  391. ExportScopeInfo: true,
  392. ExportScopePrefix: "",
  393. exportSettings: exportSettings{
  394. ExportSeparator: ".SEP.",
  395. ExportDistinguishingSuffix: ".SUF.",
  396. },
  397. DecomposeComplexMessageField: true,
  398. },
  399. expected: add_events.EventAttrs{
  400. "message": "This is a log message",
  401. "string": "stringR",
  402. "map.SEP.map_empty": nil,
  403. "map.SEP.map_string": "map_stringR",
  404. "map.SEP.map_map.SEP.map_map_string": "map_map_stringR",
  405. "slice.SEP.0": "slice_stringR",
  406. "name": "filled_nameR",
  407. "span_id": "filled_span_idR",
  408. "string.SUF.": "stringS",
  409. "map.SEP.map_empty.SUF.": nil,
  410. "map.SEP.map_string.SUF.": "map_stringS",
  411. "map.SEP.map_map.SEP.map_map_string.SUF.": "map_map_stringS",
  412. "slice.SEP.0.SUF.": "slice_stringS",
  413. "name.SUF.": "filled_nameS",
  414. "span_id.SUF.": "filled_span_idS",
  415. "string.SUF..SUF.": "stringA",
  416. "map.SEP.map_empty.SUF..SUF.": nil,
  417. "map.SEP.map_string.SUF..SUF.": "map_stringA",
  418. "map.SEP.map_map.SEP.map_map_string.SUF..SUF.": "map_map_stringA",
  419. "slice.SEP.0.SUF..SUF.": "slice_stringA",
  420. "name.SUF..SUF.": "filled_nameA",
  421. "span_id.SUF..SUF.": "filled_span_idA",
  422. "resource-attr": "resource-attr-val-1",
  423. },
  424. },
  425. {
  426. name: "EmptyPrefixesAndNonEmptySuffixComplexBody",
  427. complexBody: true,
  428. includeSpanID: false,
  429. settings: LogsSettings{
  430. ExportResourceInfo: true,
  431. ExportResourcePrefix: "",
  432. ExportScopeInfo: true,
  433. ExportScopePrefix: "",
  434. exportSettings: exportSettings{
  435. ExportSeparator: ".SEP.",
  436. ExportDistinguishingSuffix: ".SUF.",
  437. },
  438. DecomposeComplexMessageField: true,
  439. DecomposedComplexMessagePrefix: "",
  440. },
  441. expected: add_events.EventAttrs{
  442. "message": "{\"empty_map\":{},\"empty_slice\":[],\"map\":{\"map_empty\":null,\"map_map\":{\"map_map_string\":\"map_map_stringM\"},\"map_string\":\"map_stringM\"},\"name\":\"filled_nameM\",\"slice\":[\"slice_stringM\"],\"span_id\":\"filled_span_idM\",\"string\":\"stringM\"}",
  443. "string": "stringM",
  444. "map.SEP.map_empty": nil,
  445. "map.SEP.map_string": "map_stringM",
  446. "map.SEP.map_map.SEP.map_map_string": "map_map_stringM",
  447. "slice.SEP.0": "slice_stringM",
  448. "name": "filled_nameM",
  449. "span_id": "filled_span_idM",
  450. "string.SUF.": "stringR",
  451. "map.SEP.map_empty.SUF.": nil,
  452. "map.SEP.map_string.SUF.": "map_stringR",
  453. "map.SEP.map_map.SEP.map_map_string.SUF.": "map_map_stringR",
  454. "slice.SEP.0.SUF.": "slice_stringR",
  455. "name.SUF.": "filled_nameR",
  456. "span_id.SUF.": "filled_span_idR",
  457. "string.SUF..SUF.": "stringS",
  458. "map.SEP.map_empty.SUF..SUF.": nil,
  459. "map.SEP.map_string.SUF..SUF.": "map_stringS",
  460. "map.SEP.map_map.SEP.map_map_string.SUF..SUF.": "map_map_stringS",
  461. "slice.SEP.0.SUF..SUF.": "slice_stringS",
  462. "name.SUF..SUF.": "filled_nameS",
  463. "span_id.SUF..SUF.": "filled_span_idS",
  464. "string.SUF..SUF..SUF.": "stringA",
  465. "map.SEP.map_empty.SUF..SUF..SUF.": nil,
  466. "map.SEP.map_string.SUF..SUF..SUF.": "map_stringA",
  467. "map.SEP.map_map.SEP.map_map_string.SUF..SUF..SUF.": "map_map_stringA",
  468. "slice.SEP.0.SUF..SUF..SUF.": "slice_stringA",
  469. "name.SUF..SUF..SUF.": "filled_nameA",
  470. "span_id.SUF..SUF..SUF.": "filled_span_idA",
  471. "resource-attr": "resource-attr-val-1",
  472. },
  473. },
  474. {
  475. name: "EmptyPrefixesAndEmptySuffixSimpleBody",
  476. complexBody: false,
  477. includeSpanID: false,
  478. settings: LogsSettings{
  479. ExportResourceInfo: true,
  480. ExportResourcePrefix: "",
  481. ExportScopeInfo: true,
  482. ExportScopePrefix: "",
  483. exportSettings: exportSettings{
  484. ExportSeparator: ".SEP.",
  485. ExportDistinguishingSuffix: "",
  486. },
  487. DecomposeComplexMessageField: true,
  488. DecomposedComplexMessagePrefix: "",
  489. },
  490. expected: add_events.EventAttrs{
  491. "message": "This is a log message",
  492. "string": "stringA",
  493. "map.SEP.map_empty": nil,
  494. "map.SEP.map_string": "map_stringA",
  495. "map.SEP.map_map.SEP.map_map_string": "map_map_stringA",
  496. "slice.SEP.0": "slice_stringA",
  497. "name": "filled_nameA",
  498. "span_id": "filled_span_idA",
  499. "resource-attr": "resource-attr-val-1",
  500. },
  501. },
  502. {
  503. name: "EmptyPrefixesAndEmptySuffixComplexBody",
  504. complexBody: true,
  505. includeSpanID: false,
  506. settings: LogsSettings{
  507. ExportResourceInfo: true,
  508. ExportResourcePrefix: "",
  509. ExportScopeInfo: true,
  510. ExportScopePrefix: "",
  511. exportSettings: exportSettings{
  512. ExportSeparator: ".SEP.",
  513. ExportDistinguishingSuffix: "",
  514. },
  515. DecomposeComplexMessageField: true,
  516. DecomposedComplexMessagePrefix: "",
  517. },
  518. expected: add_events.EventAttrs{
  519. "message": "{\"empty_map\":{},\"empty_slice\":[],\"map\":{\"map_empty\":null,\"map_map\":{\"map_map_string\":\"map_map_stringM\"},\"map_string\":\"map_stringM\"},\"name\":\"filled_nameM\",\"slice\":[\"slice_stringM\"],\"span_id\":\"filled_span_idM\",\"string\":\"stringM\"}",
  520. "string": "stringA",
  521. "map.SEP.map_empty": nil,
  522. "map.SEP.map_string": "map_stringA",
  523. "map.SEP.map_map.SEP.map_map_string": "map_map_stringA",
  524. "slice.SEP.0": "slice_stringA",
  525. "name": "filled_nameA",
  526. "span_id": "filled_span_idA",
  527. "resource-attr": "resource-attr-val-1",
  528. },
  529. },
  530. }
  531. for _, tt := range tests {
  532. t.Run(tt.name, func(t *testing.T) {
  533. lr := testdata.GenerateLogsOneEmptyLogRecord()
  534. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  535. resource := lr.ResourceLogs().At(0).Resource()
  536. scope := lr.ResourceLogs().At(0).ScopeLogs().At(0).Scope()
  537. fillAttributes(resource.Attributes(), false, "R")
  538. fillAttributes(scope.Attributes(), false, "S")
  539. fillAttributes(ld.Attributes(), false, "A")
  540. ld.SetTimestamp(testdata.TestLogTimestamp)
  541. if tt.includeSpanID {
  542. ld.SetSpanID([8]byte{1, 1, 1, 1, 1, 1, 1, 1})
  543. }
  544. if tt.complexBody {
  545. m := ld.Body().SetEmptyMap()
  546. fillAttributes(m, false, "M")
  547. } else {
  548. ld.Body().SetStr("This is a log message")
  549. }
  550. expected := &add_events.EventBundle{
  551. Event: &add_events.Event{
  552. Thread: testLThread.Id,
  553. Log: testLLog.Id,
  554. Sev: 3,
  555. Ts: "1581452773000000789",
  556. ServerHost: testServerHost,
  557. Attrs: tt.expected,
  558. },
  559. Thread: testLThread,
  560. Log: testLLog,
  561. }
  562. was := buildEventFromLog(
  563. ld,
  564. resource,
  565. scope,
  566. testServerHost,
  567. tt.settings,
  568. )
  569. assert.Equal(t, expected, was)
  570. })
  571. }
  572. }
  573. func TestBuildEventFromLogExportResources(t *testing.T) {
  574. lr := testdata.GenerateLogsOneLogRecord()
  575. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  576. defaultAttrs := testLEventRaw.Attrs
  577. defaultAttrs["resource-attr"] = "resource-attr-val-1"
  578. expected := &add_events.EventBundle{
  579. Event: &add_events.Event{
  580. Thread: testLEventRaw.Thread,
  581. Log: testLEventRaw.Log,
  582. Sev: testLEventRaw.Sev,
  583. Ts: testLEventRaw.Ts,
  584. Attrs: defaultAttrs,
  585. ServerHost: testLEventRaw.ServerHost,
  586. },
  587. Thread: testLThread,
  588. Log: testLLog,
  589. }
  590. was := buildEventFromLog(
  591. ld,
  592. lr.ResourceLogs().At(0).Resource(),
  593. lr.ResourceLogs().At(0).ScopeLogs().At(0).Scope(),
  594. testServerHost,
  595. LogsSettings{
  596. ExportResourceInfo: true,
  597. ExportScopeInfo: true,
  598. },
  599. )
  600. assert.Equal(t, expected, was)
  601. }
  602. func TestBuildEventFromLogExportScopeInfo(t *testing.T) {
  603. lr := testdata.GenerateLogsOneLogRecord()
  604. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  605. scope := pcommon.NewInstrumentationScope()
  606. scope.SetName("test-scope")
  607. scope.SetDroppedAttributesCount(11)
  608. expected := &add_events.EventBundle{
  609. Event: &add_events.Event{
  610. Thread: testLEventRawWithScopeInfo.Thread,
  611. Log: testLEventRawWithScopeInfo.Log,
  612. Sev: testLEventRawWithScopeInfo.Sev,
  613. Ts: testLEventRawWithScopeInfo.Ts,
  614. Attrs: testLEventRawWithScopeInfo.Attrs,
  615. ServerHost: testLEventRaw.ServerHost,
  616. },
  617. Thread: testLThread,
  618. Log: testLLog,
  619. }
  620. was := buildEventFromLog(
  621. ld,
  622. lr.ResourceLogs().At(0).Resource(),
  623. scope,
  624. testServerHost,
  625. LogsSettings{
  626. ExportResourceInfo: false,
  627. ExportScopeInfo: true,
  628. },
  629. )
  630. assert.Equal(t, expected, was)
  631. }
  632. func TestBuildEventFromLogEventWithoutTimestampWithObservedTimestampUseObservedTimestamp(t *testing.T) {
  633. // When LogRecord doesn't have timestamp set, but it has ObservedTimestamp set,
  634. // ObservedTimestamp should be used
  635. lr := testdata.GenerateLogsOneLogRecord()
  636. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  637. ld.SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, 0)))
  638. ld.SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(1686235113, 0)))
  639. testLEventRaw.Ts = "1686235113000000000"
  640. // 2023-06-08 14:38:33 +0000 UTC
  641. testLEventRaw.Attrs["sca:observedTime"] = "1686235113000000000"
  642. delete(testLEventRaw.Attrs, "timestamp")
  643. delete(testLEventRaw.Attrs, "resource-attr")
  644. expected := &add_events.EventBundle{
  645. Event: testLEventRaw,
  646. Thread: testLThread,
  647. Log: testLLog,
  648. }
  649. was := buildEventFromLog(
  650. ld,
  651. lr.ResourceLogs().At(0).Resource(),
  652. lr.ResourceLogs().At(0).ScopeLogs().At(0).Scope(),
  653. testServerHost,
  654. newDefaultLogsSettings(),
  655. )
  656. assert.Equal(t, expected, was)
  657. }
  658. func TestBuildEventFromLogEventWithoutTimestampWithOutObservedTimestampUseCurrentTimestamp(t *testing.T) {
  659. // When LogRecord doesn't have timestamp and ObservedTimestamp set, current timestamp
  660. // should be used
  661. // We mock current time to ensure stability across runs
  662. now = func() time.Time { return time.Unix(123456789, 0) }
  663. currentTime := now()
  664. assert.Equal(t, currentTime, time.Unix(123456789, 0))
  665. assert.Equal(t, strconv.FormatInt(currentTime.UnixNano(), 10), "123456789000000000")
  666. lr := testdata.GenerateLogsOneLogRecord()
  667. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  668. ld.SetTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, 0)))
  669. ld.SetObservedTimestamp(pcommon.NewTimestampFromTime(time.Unix(0, 0)))
  670. testLEventRaw.Ts = strconv.FormatInt(currentTime.UnixNano(), 10)
  671. delete(testLEventRaw.Attrs, "timestamp")
  672. delete(testLEventRaw.Attrs, "sca:observedTime")
  673. delete(testLEventRaw.Attrs, "resource-attr")
  674. expected := &add_events.EventBundle{
  675. Event: testLEventRaw,
  676. Thread: testLThread,
  677. Log: testLLog,
  678. }
  679. was := buildEventFromLog(
  680. ld,
  681. lr.ResourceLogs().At(0).Resource(),
  682. lr.ResourceLogs().At(0).ScopeLogs().At(0).Scope(),
  683. testServerHost,
  684. newDefaultLogsSettings(),
  685. )
  686. assert.Equal(t, expected, was)
  687. }
  688. func extract(req *http.Request) (add_events.AddEventsRequest, error) {
  689. data, _ := io.ReadAll(req.Body)
  690. b := bytes.NewBuffer(data)
  691. reader, _ := gzip.NewReader(b)
  692. var resB bytes.Buffer
  693. _, _ = resB.ReadFrom(reader)
  694. cer := &add_events.AddEventsRequest{}
  695. err := json.Unmarshal(resB.Bytes(), cer)
  696. return *cer, err
  697. }
  698. func TestConsumeLogsShouldSucceed(t *testing.T) {
  699. createSettings := exportertest.NewNopCreateSettings()
  700. attempt := atomic.Uint64{}
  701. wasSuccessful := atomic.Bool{}
  702. addRequests := []add_events.AddEventsRequest{}
  703. lock := sync.Mutex{}
  704. server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  705. attempt.Add(1)
  706. cer, err := extract(req)
  707. lock.Lock()
  708. addRequests = append(addRequests, cer)
  709. lock.Unlock()
  710. assert.NoError(t, err, "Error reading request: %v", err)
  711. wasSuccessful.Store(true)
  712. payload, err := json.Marshal(map[string]any{
  713. "status": "success",
  714. "bytesCharged": 42,
  715. })
  716. assert.NoError(t, err)
  717. l, err := w.Write(payload)
  718. assert.Greater(t, l, 1)
  719. assert.NoError(t, err)
  720. }))
  721. defer server.Close()
  722. config := &Config{
  723. DatasetURL: server.URL,
  724. APIKey: "key-lib",
  725. Debug: true,
  726. BufferSettings: BufferSettings{
  727. MaxLifetime: 2 * time.Second,
  728. GroupBy: []string{"attributes.container_id"},
  729. RetryInitialInterval: time.Second,
  730. RetryMaxInterval: time.Minute,
  731. RetryMaxElapsedTime: time.Hour,
  732. RetryShutdownTimeout: time.Minute,
  733. },
  734. LogsSettings: LogsSettings{
  735. ExportResourceInfo: true,
  736. ExportResourcePrefix: "R#",
  737. ExportScopeInfo: true,
  738. ExportScopePrefix: "S#",
  739. exportSettings: exportSettings{
  740. ExportSeparator: "#",
  741. ExportDistinguishingSuffix: "_",
  742. },
  743. },
  744. TracesSettings: TracesSettings{
  745. exportSettings: exportSettings{
  746. ExportSeparator: "?",
  747. ExportDistinguishingSuffix: "-",
  748. },
  749. },
  750. ServerHostSettings: ServerHostSettings{
  751. ServerHost: testServerHost,
  752. },
  753. RetrySettings: exporterhelper.NewDefaultRetrySettings(),
  754. QueueSettings: exporterhelper.NewDefaultQueueSettings(),
  755. TimeoutSettings: exporterhelper.NewDefaultTimeoutSettings(),
  756. }
  757. lr1 := testdata.GenerateLogsOneLogRecord()
  758. lr2 := testdata.GenerateLogsOneLogRecord()
  759. // set attribute for the hostname, it should beat value from resource
  760. lr2.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0).Attributes().PutStr(add_events.AttrServerHost, "serverHostFromAttribute")
  761. lr2.ResourceLogs().At(0).Resource().Attributes().PutStr(add_events.AttrServerHost, "serverHostFromResource")
  762. // set attribute serverHost and host.name attributes in the resource, serverHost will win
  763. lr3 := testdata.GenerateLogsOneLogRecord()
  764. lr3.ResourceLogs().At(0).Resource().Attributes().PutStr(add_events.AttrServerHost, "serverHostFromResourceServer")
  765. lr3.ResourceLogs().At(0).Resource().Attributes().PutStr("host.name", "serverHostFromResourceHost")
  766. // set attribute host.name in the resource attribute
  767. lr4 := testdata.GenerateLogsOneLogRecord()
  768. lr4.ResourceLogs().At(0).Resource().Attributes().PutStr("host.name", "serverHostFromResourceHost")
  769. // set all possible values
  770. lr5 := testdata.GenerateLogsOneLogRecord()
  771. fillAttributes(lr5.ResourceLogs().At(0).Resource().Attributes(), true, "R")
  772. fillAttributes(lr5.ResourceLogs().At(0).ScopeLogs().At(0).Scope().Attributes(), true, "S")
  773. fillAttributes(lr5.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0).Attributes(), true, "A")
  774. ld := plog.NewLogs()
  775. ld.ResourceLogs().AppendEmpty()
  776. ld.ResourceLogs().AppendEmpty()
  777. ld.ResourceLogs().AppendEmpty()
  778. ld.ResourceLogs().AppendEmpty()
  779. ld.ResourceLogs().AppendEmpty()
  780. lr1.ResourceLogs().At(0).CopyTo(ld.ResourceLogs().At(0))
  781. lr2.ResourceLogs().At(0).CopyTo(ld.ResourceLogs().At(1))
  782. lr3.ResourceLogs().At(0).CopyTo(ld.ResourceLogs().At(2))
  783. lr4.ResourceLogs().At(0).CopyTo(ld.ResourceLogs().At(3))
  784. lr5.ResourceLogs().At(0).CopyTo(ld.ResourceLogs().At(4))
  785. logs, err := createLogsExporter(context.Background(), createSettings, config)
  786. if assert.NoError(t, err) {
  787. err = logs.Start(context.Background(), componenttest.NewNopHost())
  788. assert.NoError(t, err)
  789. assert.NotNil(t, logs)
  790. err = logs.ConsumeLogs(context.Background(), ld)
  791. assert.Nil(t, err)
  792. time.Sleep(time.Second)
  793. err = logs.Shutdown(context.Background())
  794. assert.Nil(t, err)
  795. }
  796. assert.True(t, wasSuccessful.Load())
  797. assert.Equal(t, uint64(4), attempt.Load())
  798. sort.SliceStable(addRequests, func(i, j int) bool {
  799. if addRequests[i].Session == addRequests[j].Session {
  800. return len(addRequests[i].Events) < len(addRequests[j].Events)
  801. }
  802. return addRequests[i].Session < addRequests[j].Session
  803. })
  804. assert.Equal(t,
  805. []add_events.AddEventsRequest{
  806. {
  807. AuthParams: request.AuthParams{
  808. Token: "key-lib",
  809. },
  810. AddEventsRequestParams: add_events.AddEventsRequestParams{
  811. Session: addRequests[0].Session,
  812. SessionInfo: &add_events.SessionInfo{
  813. add_events.AttrServerHost: "serverHostFromAttribute",
  814. add_events.AttrSessionKey: "0296b9a57cb379df0f35aaf2d23500d3",
  815. },
  816. Events: []*add_events.Event{
  817. {
  818. Thread: testLEventReq.Thread,
  819. Log: testLEventReq.Log,
  820. Sev: testLEventReq.Sev,
  821. Ts: testLEventReq.Ts,
  822. Attrs: map[string]any{
  823. "app": "server",
  824. "instance_num": float64(1),
  825. "dropped_attributes_count": float64(1),
  826. "message": "This is a log message",
  827. "span_id": "0102040800000000",
  828. "trace_id": "08040201000000000000000000000000",
  829. "R#resource-attr": "resource-attr-val-1",
  830. "R#serverHost": "serverHostFromResource",
  831. },
  832. ServerHost: "",
  833. },
  834. },
  835. Threads: []*add_events.Thread{testLThread},
  836. Logs: []*add_events.Log{testLLog},
  837. },
  838. },
  839. {
  840. AuthParams: request.AuthParams{
  841. Token: "key-lib",
  842. },
  843. AddEventsRequestParams: add_events.AddEventsRequestParams{
  844. Session: addRequests[1].Session,
  845. SessionInfo: &add_events.SessionInfo{
  846. add_events.AttrServerHost: "serverHostFromResourceHost",
  847. add_events.AttrSessionKey: "73b97897d80d89c9a09a3ee6ed178650",
  848. },
  849. Events: []*add_events.Event{
  850. {
  851. Thread: testLEventReq.Thread,
  852. Log: testLEventReq.Log,
  853. Sev: testLEventReq.Sev,
  854. Ts: testLEventReq.Ts,
  855. Attrs: map[string]any{
  856. "app": "server",
  857. "instance_num": float64(1),
  858. "dropped_attributes_count": float64(1),
  859. "message": "This is a log message",
  860. "span_id": "0102040800000000",
  861. "trace_id": "08040201000000000000000000000000",
  862. "R#resource-attr": "resource-attr-val-1",
  863. "R#host.name": "serverHostFromResourceHost",
  864. },
  865. },
  866. },
  867. Threads: []*add_events.Thread{testLThread},
  868. Logs: []*add_events.Log{testLLog},
  869. },
  870. },
  871. {
  872. AuthParams: request.AuthParams{
  873. Token: "key-lib",
  874. },
  875. AddEventsRequestParams: add_events.AddEventsRequestParams{
  876. Session: addRequests[2].Session,
  877. SessionInfo: &add_events.SessionInfo{
  878. add_events.AttrServerHost: "serverHostFromResourceServer",
  879. add_events.AttrSessionKey: "770e22b433d2e9a31fa9a81abf3b9b87",
  880. },
  881. Events: []*add_events.Event{
  882. {
  883. Thread: testLEventReq.Thread,
  884. Log: testLEventReq.Log,
  885. Sev: testLEventReq.Sev,
  886. Ts: testLEventReq.Ts,
  887. Attrs: map[string]any{
  888. "app": "server",
  889. "instance_num": float64(1),
  890. "dropped_attributes_count": float64(1),
  891. "message": "This is a log message",
  892. "span_id": "0102040800000000",
  893. "trace_id": "08040201000000000000000000000000",
  894. "R#resource-attr": "resource-attr-val-1",
  895. "R#host.name": "serverHostFromResourceHost",
  896. "R#serverHost": "serverHostFromResourceServer",
  897. },
  898. },
  899. },
  900. Threads: []*add_events.Thread{testLThread},
  901. Logs: []*add_events.Log{testLLog},
  902. },
  903. },
  904. {
  905. AuthParams: request.AuthParams{
  906. Token: "key-lib",
  907. },
  908. AddEventsRequestParams: add_events.AddEventsRequestParams{
  909. Session: addRequests[3].Session,
  910. SessionInfo: &add_events.SessionInfo{
  911. add_events.AttrServerHost: "foo",
  912. add_events.AttrSessionKey: "caedd419dc354c24a69aac7508890ec1",
  913. },
  914. Events: []*add_events.Event{
  915. {
  916. Thread: testLEventReq.Thread,
  917. Log: testLEventReq.Log,
  918. Sev: testLEventReq.Sev,
  919. Ts: testLEventReq.Ts,
  920. Attrs: map[string]any{
  921. "app": "server",
  922. "instance_num": float64(1),
  923. "dropped_attributes_count": float64(1),
  924. "message": "This is a log message",
  925. "span_id": "0102040800000000",
  926. "trace_id": "08040201000000000000000000000000",
  927. "R#resource-attr": "resource-attr-val-1",
  928. },
  929. },
  930. {
  931. Thread: testLEventReq.Thread,
  932. Log: testLEventReq.Log,
  933. Sev: testLEventReq.Sev,
  934. Ts: testLEventReq.Ts,
  935. Attrs: map[string]any{
  936. "app": "server",
  937. "instance_num": float64(1),
  938. "dropped_attributes_count": float64(1),
  939. "message": "This is a log message",
  940. "span_id": "0102040800000000",
  941. "trace_id": "08040201000000000000000000000000",
  942. "string": "stringA",
  943. "double": 2.0,
  944. "bool": true,
  945. "empty": nil,
  946. "int": float64(3),
  947. "map#map_empty": nil,
  948. "map#map_string": "map_stringA",
  949. "map#map_map#map_map_string": "map_map_stringA",
  950. "slice#0": "slice_stringA",
  951. "name": "filled_nameA",
  952. "span_id_": "filled_span_idA",
  953. "S#string": "stringS",
  954. "S#double": 2.0,
  955. "S#bool": true,
  956. "S#empty": nil,
  957. "S#int": float64(3),
  958. "S#map#map_empty": nil,
  959. "S#map#map_string": "map_stringS",
  960. "S#map#map_map#map_map_string": "map_map_stringS",
  961. "S#slice#0": "slice_stringS",
  962. "S#name": "filled_nameS",
  963. "S#span_id": "filled_span_idS",
  964. "R#string": "stringR",
  965. "R#double": 2.0,
  966. "R#bool": true,
  967. "R#empty": nil,
  968. "R#int": float64(3),
  969. "R#map#map_empty": nil,
  970. "R#map#map_string": "map_stringR",
  971. "R#map#map_map#map_map_string": "map_map_stringR",
  972. "R#slice#0": "slice_stringR",
  973. "R#name": "filled_nameR",
  974. "R#span_id": "filled_span_idR",
  975. "R#resource-attr": "resource-attr-val-1",
  976. },
  977. },
  978. },
  979. Threads: []*add_events.Thread{testLThread},
  980. Logs: []*add_events.Log{testLLog},
  981. },
  982. },
  983. },
  984. addRequests,
  985. )
  986. }
  987. func makeLogRecordWithSeverityNumberAndSeverityText(sevNum int, sevText string) plog.LogRecord {
  988. lr := testdata.GenerateLogsOneLogRecord()
  989. ld := lr.ResourceLogs().At(0).ScopeLogs().At(0).LogRecords().At(0)
  990. ld.SetSeverityNumber(plog.SeverityNumber(sevNum))
  991. ld.SetSeverityText(sevText)
  992. return ld
  993. }
  994. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextInvalidValues(t *testing.T) {
  995. // Invalid values get mapped to info (3 - INFO)
  996. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "")
  997. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  998. ld = makeLogRecordWithSeverityNumberAndSeverityText(-1, "")
  999. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  1000. ld = makeLogRecordWithSeverityNumberAndSeverityText(25, "")
  1001. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  1002. ld = makeLogRecordWithSeverityNumberAndSeverityText(100, "")
  1003. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  1004. }
  1005. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetTraceLogLevel(t *testing.T) {
  1006. // trace
  1007. ld := makeLogRecordWithSeverityNumberAndSeverityText(1, "")
  1008. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1009. ld = makeLogRecordWithSeverityNumberAndSeverityText(2, "")
  1010. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1011. ld = makeLogRecordWithSeverityNumberAndSeverityText(3, "")
  1012. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1013. ld = makeLogRecordWithSeverityNumberAndSeverityText(4, "")
  1014. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1015. }
  1016. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetDebugLogLevel(t *testing.T) {
  1017. // debug
  1018. ld := makeLogRecordWithSeverityNumberAndSeverityText(5, "")
  1019. assert.Equal(t, dataSetLogLevelDebug, mapOtelSeverityToDataSetSeverity(ld))
  1020. ld = makeLogRecordWithSeverityNumberAndSeverityText(6, "")
  1021. assert.Equal(t, dataSetLogLevelDebug, mapOtelSeverityToDataSetSeverity(ld))
  1022. ld = makeLogRecordWithSeverityNumberAndSeverityText(7, "")
  1023. assert.Equal(t, dataSetLogLevelDebug, mapOtelSeverityToDataSetSeverity(ld))
  1024. ld = makeLogRecordWithSeverityNumberAndSeverityText(8, "")
  1025. assert.Equal(t, dataSetLogLevelDebug, mapOtelSeverityToDataSetSeverity(ld))
  1026. }
  1027. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetInfoLogLevel(t *testing.T) {
  1028. // info
  1029. ld := makeLogRecordWithSeverityNumberAndSeverityText(9, "")
  1030. assert.Equal(t, dataSetLogLevelInfo, mapOtelSeverityToDataSetSeverity(ld))
  1031. ld = makeLogRecordWithSeverityNumberAndSeverityText(10, "")
  1032. assert.Equal(t, dataSetLogLevelInfo, mapOtelSeverityToDataSetSeverity(ld))
  1033. ld = makeLogRecordWithSeverityNumberAndSeverityText(11, "")
  1034. assert.Equal(t, dataSetLogLevelInfo, mapOtelSeverityToDataSetSeverity(ld))
  1035. ld = makeLogRecordWithSeverityNumberAndSeverityText(12, "")
  1036. assert.Equal(t, dataSetLogLevelInfo, mapOtelSeverityToDataSetSeverity(ld))
  1037. }
  1038. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetWarnLogLevel(t *testing.T) {
  1039. // warn
  1040. ld := makeLogRecordWithSeverityNumberAndSeverityText(13, "")
  1041. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1042. ld = makeLogRecordWithSeverityNumberAndSeverityText(14, "")
  1043. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1044. ld = makeLogRecordWithSeverityNumberAndSeverityText(15, "")
  1045. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1046. ld = makeLogRecordWithSeverityNumberAndSeverityText(16, "")
  1047. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1048. }
  1049. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetErrorLogLevel(t *testing.T) {
  1050. // error
  1051. ld := makeLogRecordWithSeverityNumberAndSeverityText(17, "")
  1052. assert.Equal(t, dataSetLogLevelError, mapOtelSeverityToDataSetSeverity(ld))
  1053. ld = makeLogRecordWithSeverityNumberAndSeverityText(18, "")
  1054. assert.Equal(t, dataSetLogLevelError, mapOtelSeverityToDataSetSeverity(ld))
  1055. ld = makeLogRecordWithSeverityNumberAndSeverityText(19, "")
  1056. assert.Equal(t, dataSetLogLevelError, mapOtelSeverityToDataSetSeverity(ld))
  1057. ld = makeLogRecordWithSeverityNumberAndSeverityText(20, "")
  1058. assert.Equal(t, dataSetLogLevelError, mapOtelSeverityToDataSetSeverity(ld))
  1059. }
  1060. func TestOtelSeverityToDataSetSeverityWithSeverityNumberNoSeverityTextDataSetFatalLogLevel(t *testing.T) {
  1061. // fatal
  1062. ld := makeLogRecordWithSeverityNumberAndSeverityText(21, "")
  1063. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1064. ld = makeLogRecordWithSeverityNumberAndSeverityText(22, "")
  1065. ld.SetSeverityNumber(22)
  1066. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1067. ld = makeLogRecordWithSeverityNumberAndSeverityText(23, "")
  1068. ld.SetSeverityNumber(22)
  1069. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1070. ld = makeLogRecordWithSeverityNumberAndSeverityText(24, "")
  1071. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1072. }
  1073. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberInvalidValues(t *testing.T) {
  1074. // invalid values
  1075. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "a")
  1076. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  1077. ld = makeLogRecordWithSeverityNumberAndSeverityText(0, "infoinfo")
  1078. assert.Equal(t, defaultDataSetSeverityLevel, mapOtelSeverityToDataSetSeverity(ld))
  1079. }
  1080. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetTraceLogLevel(t *testing.T) {
  1081. // trace
  1082. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "trace")
  1083. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1084. }
  1085. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetDebugLogLevel(t *testing.T) {
  1086. // debug
  1087. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "debug")
  1088. assert.Equal(t, dataSetLogLevelDebug, mapOtelSeverityToDataSetSeverity(ld))
  1089. }
  1090. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetInfoLogLevel(t *testing.T) {
  1091. // info
  1092. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "info")
  1093. assert.Equal(t, dataSetLogLevelInfo, mapOtelSeverityToDataSetSeverity(ld))
  1094. ld = makeLogRecordWithSeverityNumberAndSeverityText(0, "informational")
  1095. ld.SetSeverityText("informational")
  1096. }
  1097. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetInfoWarnLevel(t *testing.T) {
  1098. // warn
  1099. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "warn")
  1100. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1101. ld = makeLogRecordWithSeverityNumberAndSeverityText(0, "warning")
  1102. assert.Equal(t, dataSetLogLevelWarn, mapOtelSeverityToDataSetSeverity(ld))
  1103. }
  1104. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetInfoErrorLevel(t *testing.T) {
  1105. // error
  1106. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "error")
  1107. assert.Equal(t, dataSetLogLevelError, mapOtelSeverityToDataSetSeverity(ld))
  1108. }
  1109. func TestOtelSeverityToDataSetSeverityWithSeverityTextNoSeverityNumberDataSetInfoFatalLevel(t *testing.T) {
  1110. // fatal
  1111. ld := makeLogRecordWithSeverityNumberAndSeverityText(0, "fatal")
  1112. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1113. ld = makeLogRecordWithSeverityNumberAndSeverityText(0, "fatal")
  1114. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1115. ld = makeLogRecordWithSeverityNumberAndSeverityText(0, "emergency")
  1116. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1117. }
  1118. func TestOtelSeverityToDataSetSeverityWithSeverityNumberAndSeverityTextSeverityNumberHasPriority(t *testing.T) {
  1119. // If provided, SeverityNumber has priority over SeverityText
  1120. ld := makeLogRecordWithSeverityNumberAndSeverityText(3, "debug")
  1121. assert.Equal(t, dataSetLogLevelTrace, mapOtelSeverityToDataSetSeverity(ld))
  1122. ld = makeLogRecordWithSeverityNumberAndSeverityText(22, "info")
  1123. assert.Equal(t, dataSetLogLevelFatal, mapOtelSeverityToDataSetSeverity(ld))
  1124. }