Search code examples
htmlspringspring-boottracebrave

Convert Span Id from long to String


How can I convert a Brave Span id, which I've retrieved from span.context().spanId() to a String containing its 64 lower-hex encoded bits. Sleuth contained a static utility method, Span.idToHex() which did this. Is their a Brave equivalent? Long.toHexString() is a candidate, but we saw issues where we had to left pad our string.


Solution

  • I see that since Brave version 5.6.0 there is the spanIdString() which Returns the hex representation of the span's ID.

    This internally uses the toLowerHex(long v) in HexCodec. This has the current form since version 4.9.0 as far as I can tell. Before that, the method existed since version 4.0.0 but in some different form. This method is public and you could use it, however with caution because as the package name hints it isn't public API and I would expect it to be possible to change in future releases.

    Other than that I had a look at Sleuth's Span.idToHex() and see that internally uses the Long.toHexString(). It doesn't do anything more.

    Long.toHexString() is a candidate, but we saw issues where we had to left pad our string.

    The Brave's spanId is an 8-byte number. The hex representation is potentially a 16 character string. This string doesn't have to be left padded. This is a matter of formatting the value while presenting it.

    For example this:

    System.out.println(String.format("%s", Long.toHexString(Long.MIN_VALUE)));
    System.out.println(String.format("%s", Long.toHexString(-1L)));
    System.out.println(String.format("%s", Long.toHexString(0L)));
    System.out.println(String.format("%s", Long.toHexString(1L)));
    System.out.println(String.format("%s", Long.toHexString(Long.MAX_VALUE)));
    
    System.out.println(String.format("%X", Long.MIN_VALUE));
    System.out.println(String.format("%X", -1L));
    System.out.println(String.format("%X", 0L));
    System.out.println(String.format("%X", 1L));
    System.out.println(String.format("%X", Long.MAX_VALUE));
    

    Would output this:

    8000000000000000
    ffffffffffffffff
    0
    1
    7fffffffffffffff
    
    8000000000000000
    FFFFFFFFFFFFFFFF
    0
    1
    7FFFFFFFFFFFFFFF
    

    These are valid hex values and there is no padding.

    If you want it represented with zero padding you may do it yourself as you already do. I would probably do it like that:

    System.out.println(String.format("%016X", Long.MIN_VALUE));
    System.out.println(String.format("%016X", -1L));
    System.out.println(String.format("%016X", 0L));
    System.out.println(String.format("%016X", 1L));
    System.out.println(String.format("%016X", Long.MAX_VALUE));
    

    That would print:

    8000000000000000
    FFFFFFFFFFFFFFFF
    0000000000000000
    0000000000000001
    7FFFFFFFFFFFFFFF
    

    Hope this helps!