@@ -51,6 +51,7 @@ options are listed below,
51
51
### Stream and index rules
52
52
53
53
#### Define a Group
54
+
54
55
``` java
55
56
// build a group sw_record for Stream with 2 shards and ttl equals to 3 days
56
57
Group g = Group . newBuilder(). setMetadata(Metadata . newBuilder(). setName(" sw_record" ))
@@ -299,6 +300,91 @@ Measure m = Measure.newBuilder()
299
300
client. define(m);
300
301
```
301
302
303
+ ### Trace and index rules
304
+
305
+ ` Trace ` is a first-class model for storing tracing data (binary span payloads plus searchable tags). You can define it directly via ` BanyanDBClient ` .
306
+
307
+ #### Define a Group
308
+ ``` java
309
+ // build a group sw_trace for Trace with 2 shards and ttl equals to 7 days
310
+ Group g = Group . newBuilder(). setMetadata(Metadata . newBuilder(). setName(" sw_trace" ))
311
+ .setCatalog(Catalog . CATALOG_TRACE )
312
+ .setResourceOpts(ResourceOpts . newBuilder()
313
+ .setShardNum(2 )
314
+ .setSegmentInterval(
315
+ IntervalRule . newBuilder()
316
+ .setUnit(
317
+ IntervalRule . Unit . UNIT_DAY )
318
+ .setNum(
319
+ 1 ))
320
+ .setTtl(
321
+ IntervalRule . newBuilder()
322
+ .setUnit(
323
+ IntervalRule . Unit . UNIT_DAY )
324
+ .setNum(
325
+ 7 )))
326
+ .build();
327
+ client. define(g);
328
+ ```
329
+
330
+ #### Define a Trace schema
331
+
332
+ ``` java
333
+ // Create a Trace schema with tag definitions and required identifiers
334
+ BanyandbDatabase . Trace trace = BanyandbDatabase . Trace . newBuilder()
335
+ .setMetadata(Metadata . newBuilder()
336
+ .setGroup(" sw_trace" )
337
+ .setName(" trace_data" ))
338
+ // Define searchable tags (order matters when writing)
339
+ .addTags(BanyandbDatabase . TraceTagSpec . newBuilder()
340
+ .setName(" trace_id" )
341
+ .setType(TagType . TAG_TYPE_STRING ))
342
+ .addTags(BanyandbDatabase . TraceTagSpec . newBuilder()
343
+ .setName(" span_id" )
344
+ .setType(TagType . TAG_TYPE_STRING ))
345
+ .addTags(BanyandbDatabase . TraceTagSpec . newBuilder()
346
+ .setName(" service_name" )
347
+ .setType(TagType . TAG_TYPE_STRING ))
348
+ .addTags(BanyandbDatabase . TraceTagSpec . newBuilder()
349
+ .setName(" start_time" )
350
+ .setType(TagType . TAG_TYPE_TIMESTAMP ))
351
+ // Mandatory identifiers
352
+ .setTraceIdTagName(" trace_id" )
353
+ .setTimestampTagName(" start_time" )
354
+ .build();
355
+ client. define(trace);
356
+ ```
357
+
358
+ #### Define IndexRule and IndexRuleBinding
359
+
360
+ ``` java
361
+ // Index start_time for range queries and ordering
362
+ IndexRule ir = IndexRule . newBuilder()
363
+ .setMetadata(Metadata . newBuilder()
364
+ .setGroup(" sw_trace" )
365
+ .setName(" start_time" ))
366
+ .addTags(" start_time" )
367
+ .setType(IndexRule . Type . TYPE_TREE )
368
+ .build();
369
+ client. define(ir);
370
+
371
+ // Bind the index rule to the Trace schema
372
+ IndexRuleBinding irb = IndexRuleBinding . newBuilder()
373
+ .setMetadata(Metadata . newBuilder()
374
+ .setGroup(" sw_trace" )
375
+ .setName(" trace_binding" ))
376
+ .setSubject(BanyandbDatabase . Subject . newBuilder()
377
+ .setCatalog(Catalog . CATALOG_TRACE )
378
+ .setName(" trace_data" ))
379
+ .addAllRules(Arrays . asList(" start_time" ))
380
+ .setBeginAt(TimeUtils . buildTimestamp(ZonedDateTime . of(2024 , 1 , 1 , 0 , 0 , 0 , 0 , ZoneOffset . UTC )))
381
+ .setExpireAt(TimeUtils . buildTimestamp(DEFAULT_EXPIRE_AT ))
382
+ .build();
383
+ client. define(irb);
384
+ ```
385
+
386
+ Note: Group lifecycle stages (hot/warm/cold) also apply to the Trace catalog.
387
+
302
388
### Define a Property
303
389
304
390
``` java
@@ -444,6 +530,49 @@ MeasureQueryResponse resp = client.query(query);
444
530
Trace trace = resp. getTrace();
445
531
```
446
532
533
+ ### Trace
534
+
535
+ Construct a ` TraceQuery ` to search traces by tags and/or time range. The query returns a list of traces, each containing spans with binary content.
536
+
537
+ ``` java
538
+ // Optional time range
539
+ Instant end = Instant . now();
540
+ Instant begin = end. minus(15 , ChronoUnit . MINUTES );
541
+
542
+ // Create a query for trace schema: group=sw_trace, name=trace_data
543
+ TraceQuery query = new TraceQuery (Lists . newArrayList(" sw_trace" ), " trace_data" ,
544
+ // with or without time range
545
+ new TimestampRange (begin. toEpochMilli(), end. toEpochMilli()),
546
+ // project on tags you want to sort/filter by
547
+ ImmutableSet . of(" start_time" , " service_name" ));
548
+
549
+ // Filter by trace_id
550
+ query. and(PairQueryCondition . StringQueryCondition . eq(" trace_id" , " trace-query-test-12345" ));
551
+
552
+ // Order and paginate
553
+ query. setOrderBy(new AbstractQuery .OrderBy (" start_time" , AbstractQuery . Sort . DESC ));
554
+ query. setLimit(10 );
555
+ query. setOffset(0 );
556
+
557
+ // Optionally restrict to lifecycle stages
558
+ query. stages(ImmutableSet . of(" warm" , " cold" ));
559
+
560
+ // Enable query execution tracing (diagnostics)
561
+ query. enableTrace();
562
+
563
+ // Execute
564
+ TraceQueryResponse resp = client. query(query);
565
+ // Traces (data) with spans (binary payload)
566
+ resp. getTraces(). forEach(t - > {
567
+ // t.getSpansList() -> spans; t.getTraceId() if defined in server response
568
+ });
569
+
570
+ // Execution trace (diagnostics), if enabled
571
+ String executionTrace = resp. getTraceResult();
572
+ ```
573
+
574
+ Tip: ` StreamQueryResponse.getTrace() ` and ` MeasureQueryResponse.getTrace() ` return the execution trace of the query, not the Trace data model. Use ` TraceQuery ` /` TraceQueryResponse ` to fetch tracing data.
575
+
447
576
### Property
448
577
449
578
Query properties:
@@ -580,6 +709,30 @@ CompletableFuture<Void> f = measureBulkWriteProcessor.add(measureWrite);
580
709
f. get(10 , TimeUnit . SECONDS );
581
710
```
582
711
712
+ ### Trace
713
+
714
+ ` Trace ` writes use gRPC bidirectional streaming as well. Build a ` TraceBulkWriteProcessor ` , then create ` TraceWrite ` objects carrying tags and a binary span payload.
715
+
716
+ ``` java
717
+ // build a TraceBulkWriteProcessor from client
718
+ TraceBulkWriteProcessor traceBulkWriteProcessor = client. buildTraceWriteProcessor(maxBulkSize, flushInterval, concurrency, timeout);
719
+
720
+ // Create and send a trace write
721
+ TraceWrite traceWrite = client. createTraceWrite(" sw_trace" , " trace_data" )
722
+ // tag order must follow schema definition
723
+ .tag(" trace_id" , Value . stringTagValue(" trace-query-test-12345" ))
724
+ .tag(" span_id" , Value . stringTagValue(" span-1" ))
725
+ .tag(" service_name" , Value . stringTagValue(" order-test-service" ))
726
+ .tag(" start_time" , Value . timestampTagValue(Instant . now(). toEpochMilli()))
727
+ // binary span payload (your tracing format bytes)
728
+ .span(" span-bytes" . getBytes())
729
+ // optional write version
730
+ .version(1L );
731
+
732
+ CompletableFuture<Void > f = traceBulkWriteProcessor. add(traceWrite);
733
+ f. get(10 , TimeUnit . SECONDS );
734
+ ```
735
+
583
736
### Property
584
737
585
738
Unlike ` Stream ` and ` Measure ` , ` Property ` is a single write operation. The ` Property ` object is created and sent to the server.
@@ -608,9 +761,9 @@ ApplyResponse response = client.apply(property, Strategy.STRATEGY_MERGE);
608
761
609
762
## Delete
610
763
611
- ### Stream and Measure
764
+ ### Stream / Measure / Trace
612
765
613
- The ` Stream ` and ` Measure ` are deleted by the TTL mechanism. You can set the TTL when defining the group schema.
766
+ ` Stream ` , ` Measure ` , and ` Trace ` are deleted by the TTL mechanism. Set TTL when defining the group schema.
614
767
615
768
### Property
616
769
0 commit comments