]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: log: support true cbor binary encoding
authorAurelien DARRAGON <adarragon@haproxy.com>
Tue, 23 Apr 2024 17:13:40 +0000 (19:13 +0200)
committerAurelien DARRAGON <adarragon@haproxy.com>
Fri, 26 Apr 2024 16:39:32 +0000 (18:39 +0200)
CBOR in hex format as implemented in previous commit is convenient because
the produced output is portable and can easily be embedded in regular
syslog payloads.

However, one of the goal of CBOR implementation is to be able to produce
"Concise Binary" object representation. Here is an excerpt from cbor.io
website:

  "Some applications also benefit from CBOR itself being encoded in
   binary. This saves bulk and allows faster processing."

Currently we don't offer that with '+cbor', quite the opposite actually
since a text string encoded with '+cbor' option will be larger than a
text string encoded with '+json' or without encoding at all, because for
each CBOR binary byte, 2 characters will be emitted.

Hopefully, the sink/log API allows for binary data to be passed as
parameter, this is because all relevant functions in the chain don't rely
on the terminating NULL byte and take a string pointer + string length as
parameter. We can actually rely on this property to support the '+bin'
option when combined with '+cbor' to produce RAW binary CBOR output.
Be careful though, as this is only intended for use with set-var-fmt or to
send binary data to capable UDP/ring endpoints.

Example:
  log-format "%{+cbor,+bin}o %(test)[bin(00AABB)]"

Will produce:
  bf64746573745f4300aabbffff

(output was piped to `hexdump  -ve '1/1 "%.2x"'` to dump raw bytes as HEX
characters)

With cbor.me pretty printer, it gives us:
  BF              # map(*)
     64           # text(4)
        74657374  # "test"
     5F           # bytes(*)
        43        # bytes(3)
           00AABB # "\u0000\xAA\xBB"
        FF        # primitive(*)
     FF           # primitive(*)

doc/configuration.txt
src/log.c

index 0a111eb0c6bdc0eeb4dcd7dca0cdc1876e29e6a8..afcf4488b34726adb61c5541f24ac2d5539adf73 100644 (file)
@@ -25759,6 +25759,10 @@ Flags are :
           syslog endpoints.
           As with json encoding, incomplete numerical values will be encoded
           as-is and '+E' option will be ignored.
+          When combined with '+bin' option, it will directly generate raw
+          binary CBOR payload. Be careful, because it will obviously generate
+          non-printable chars, thus it is mainly intented for use with
+          set-var-fmt, rings and binary-capable log endpoints.
 
   Example:
 
index 6354f63a8e96954fe269beff4a8f5de74af3833f..2e8e1b28154c8327fd4e2dbe84d2b897e45c8ce2 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1774,8 +1774,15 @@ static char *_encode_byte_hex(char *start, char *stop, unsigned char byte)
 static char *_lf_cbor_encode_byte(struct cbor_encode_ctx *cbor_ctx,
                                   char *start, char *stop, unsigned char byte)
 {
-       __maybe_unused struct lf_buildctx *ctx = cbor_ctx->e_byte_fct_ctx;
+       struct lf_buildctx *ctx = cbor_ctx->e_byte_fct_ctx;
 
+       if (ctx->options & LOG_OPT_BIN) {
+               /* raw output */
+               if ((stop - start) < 1)
+                       return NULL;
+               *start++ = byte;
+               return start;
+       }
        return _encode_byte_hex(start, stop, byte);
 }