diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1514d80e47..20921e8641 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -547,7 +547,7 @@ jobs: done echo "🔍 Connector-only PR — scoping tests to: $CONNECTOR_NAMES" cargo nextest run \ - --features grpc-server/connector-request-kafka \ + --features grpc-server/connector-request-kafka,grpc-server/log-transformations \ --config-file .nextest.toml \ --profile ci \ --no-tests=warn \ @@ -555,7 +555,7 @@ jobs: else echo "🔍 Running full test suite (event=$EVENT)" cargo nextest run \ - --features grpc-server/connector-request-kafka \ + --features grpc-server/connector-request-kafka,grpc-server/log-transformations \ --config-file .nextest.toml \ --profile ci \ -E "$SCHEMA_EXCLUDE" diff --git a/Cargo.lock b/Cargo.lock index 6c977ddc91..e0458e5bf4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,7 +168,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "socket2 0.6.3", - "time 0.3.47", + "time 0.3.55", "tracing", "url 2.5.8", ] @@ -315,7 +315,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -326,14 +326,14 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arc-swap" @@ -392,7 +392,7 @@ dependencies = [ "memchr", "proc-macro2", "quote", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "serde", "serde_derive", "syn 2.0.117", @@ -662,6 +662,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bisync" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5020822f6d6f23196ccaf55e228db36f9de1cf788052b37992e17cbc96ec41a7" +dependencies = [ + "bisync_macros", +] + +[[package]] +name = "bisync_macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d21f40d350a700f6aa107e45fb26448cf489d34794b2ba4522181dc9f1173af6" + [[package]] name = "bit-set" version = "0.5.3" @@ -752,6 +767,31 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bon" +version = "3.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a602c73c7b0148ec6d12af6fd5cc7a46e2eacc8878271a999abac56eed12f561" +dependencies = [ + "bon-macros", + "rustversion", +] + +[[package]] +name = "bon-macros" +version = "3.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dee98b0db6a962de883bf5d20362dee4d7ca0d12fe39a7c6c73c844e1cd7c1f" +dependencies = [ + "darling 0.21.3", + "ident_case", + "prettyplease", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.117", +] + [[package]] name = "borsh" version = "1.6.1" @@ -821,9 +861,9 @@ dependencies = [ [[package]] name = "build_info" version = "0.1.0" -source = "git+https://github.com/juspay/framework-libs-rs?rev=243562041252fe5897ce888d20b715ffdc3767ce#243562041252fe5897ce888d20b715ffdc3767ce" +source = "git+https://github.com/juspay/framework-libs-rs?rev=76613f5d0c72fd3d26a3403ae859c2a7545e8dd2#76613f5d0c72fd3d26a3403ae859c2a7545e8dd2" dependencies = [ - "cargo_metadata 0.19.2", + "cargo_metadata 0.23.1", "vergen-gix", ] @@ -912,6 +952,16 @@ dependencies = [ "serde", ] +[[package]] +name = "cargo-platform" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "cargo_metadata" version = "0.18.1" @@ -919,7 +969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", - "cargo-platform", + "cargo-platform 0.1.9", "semver", "serde", "serde_json", @@ -933,7 +983,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", - "cargo-platform", + "cargo-platform 0.1.9", + "semver", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "cargo_metadata" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" +dependencies = [ + "camino", + "cargo-platform 0.3.3", "semver", "serde", "serde_json", @@ -1173,7 +1237,7 @@ dependencies = [ "serde_urlencoded", "strum 0.26.3", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "url 2.5.8", "urlencoding", "utoipa", @@ -1281,7 +1345,7 @@ dependencies = [ "sha2", "strum 0.26.3", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tracing", "ucs_cards", "ucs_common_enums", @@ -1371,7 +1435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding 2.3.2", - "time 0.3.47", + "time 0.3.55", "version_check 0.9.5", ] @@ -1479,7 +1543,7 @@ dependencies = [ "libc", "mio 0.8.11", "parking_lot", - "signal-hook", + "signal-hook 0.3.18", "signal-hook-mio", "winapi", ] @@ -1509,16 +1573,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", -] - [[package]] name = "darling" version = "0.21.3" @@ -1539,20 +1593,6 @@ dependencies = [ "darling_macro 0.23.0", ] -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.11.1", - "syn 2.0.117", -] - [[package]] name = "darling_core" version = "0.21.3" @@ -1580,17 +1620,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core 0.20.11", - "quote", - "syn 2.0.117", -] - [[package]] name = "darling_macro" version = "0.21.3" @@ -1615,9 +1644,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "6.1.0" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1628,55 +1657,54 @@ dependencies = [ ] [[package]] -name = "der" -version = "0.7.10" +name = "defmt" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", + "bitflags 1.3.2", + "defmt-macros", ] [[package]] -name = "deranged" -version = "0.5.8" +name = "defmt-macros" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ - "powerfmt", - "serde_core", + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] -name = "derive_builder" -version = "0.20.2" +name = "defmt-parser" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "derive_builder_macro", + "thiserror 2.0.18", ] [[package]] -name = "derive_builder_core" -version = "0.20.2" +name = "der" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "darling 0.20.11", - "proc-macro2", - "quote", - "syn 2.0.117", + "const-oid", + "pem-rfc7468", + "zeroize", ] [[package]] -name = "derive_builder_macro" -version = "0.20.2" +name = "deranged" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "derive_builder_core", - "syn 2.0.117", + "serde_core", ] [[package]] @@ -1728,7 +1756,7 @@ dependencies = [ "itoa", "pq-sys", "serde_json", - "time 0.3.47", + "time 0.3.55", ] [[package]] @@ -1806,7 +1834,7 @@ dependencies = [ "serde_urlencoded", "strum 0.26.3", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tonic 0.14.5", "tracing", "ucs_cards", @@ -1899,7 +1927,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1943,6 +1971,7 @@ dependencies = [ "injector", "interfaces", "lazy_static", + "log_utils", "mime 0.3.17", "once_cell", "opentelemetry", @@ -1978,15 +2007,6 @@ dependencies = [ "regex", ] -[[package]] -name = "faster-hex" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" -dependencies = [ - "serde", -] - [[package]] name = "faster-hex" version = "0.10.0" @@ -1999,9 +2019,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" [[package]] name = "fdeflate" @@ -2069,13 +2089,12 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -2387,33 +2406,37 @@ dependencies = [ [[package]] name = "gix" -version = "0.71.0" +version = "0.86.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61e71ec6817fc3c9f12f812682cfe51ee6ea0d2e27e02fc3849c35524617435" +checksum = "bb3790fd8981cba7949f1ba924ef865d902df731627bc5998d14164063892fce" dependencies = [ "gix-actor", "gix-attributes", "gix-command", "gix-commitgraph", "gix-config", + "gix-credentials", "gix-date", "gix-diff", "gix-dir", "gix-discover", - "gix-features 0.41.1", + "gix-error", + "gix-features", "gix-filter", - "gix-fs 0.14.0", + "gix-fs", "gix-glob", - "gix-hash 0.17.0", + "gix-hash", "gix-hashtable", "gix-ignore", "gix-index", "gix-lock", + "gix-negotiate", "gix-object", "gix-odb", "gix-pack", "gix-path", "gix-pathspec", + "gix-prompt", "gix-protocol", "gix-ref", "gix-refspec", @@ -2425,44 +2448,45 @@ dependencies = [ "gix-submodule", "gix-tempfile", "gix-trace", + "gix-transport", "gix-traverse", "gix-url", - "gix-utils 0.2.0", - "gix-validate 0.9.4", + "gix-utils", + "gix-validate", "gix-worktree", - "once_cell", + "gix-worktree-state", + "gix-worktree-stream", + "gix-zlib", + "nonempty", "parking_lot", - "signal-hook", + "signal-hook 0.4.4", "smallvec", "thiserror 2.0.18", ] [[package]] name = "gix-actor" -version = "0.34.0" +version = "0.41.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f438c87d4028aca4b82f82ba8d8ab1569823cfb3e5bc5fa8456a71678b2a20e7" +checksum = "33f9308ad6fd35b2a865cbe4117ac61b2be59e4a9ef1621c7a9794f7c8e52c5b" dependencies = [ "bstr", "gix-date", - "gix-utils 0.2.0", - "itoa", - "thiserror 2.0.18", - "winnow 0.7.15", + "gix-error", ] [[package]] name = "gix-attributes" -version = "0.25.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e25825e0430aa11096f8b65ced6780d4a96a133f81904edceebb5344c8dd7f" +checksum = "c31c593692ebdc1e38858d9a2b56f6a594c501e24a38971fe6685571f5a07be0" dependencies = [ "bstr", + "gix-features", "gix-glob", "gix-path", "gix-quote", "gix-trace", - "kstring", "smallvec", "thiserror 2.0.18", "unicode-bom", @@ -2470,27 +2494,27 @@ dependencies = [ [[package]] name = "gix-bitmap" -version = "0.2.16" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d982fc7ef0608e669851d0d2a6141dae74c60d5a27e8daa451f2a4857bbf41e2" +checksum = "7cd1d118d0f5d88b96e6f6e13b566475fef4797ead4a02c26fed36c1375066f7" dependencies = [ - "thiserror 2.0.18", + "gix-error", ] [[package]] name = "gix-chunk" -version = "0.4.12" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c356b3825677cb6ff579551bb8311a81821e184453cbd105e2fc5311b288eeb" +checksum = "b2a871e5cab12ba568845714473505deefffb3c04eb47f4708ce344cd459c1cc" dependencies = [ - "thiserror 2.0.18", + "gix-error", ] [[package]] name = "gix-command" -version = "0.5.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0378995847773a697f8e157fe2963ecf3462fe64be05b7b3da000b3b472def8" +checksum = "cf4363accdf6ef7ba861871d2d521ab7418a04aaaed919fadb022af71d379b12" dependencies = [ "bstr", "gix-path", @@ -2501,43 +2525,42 @@ dependencies = [ [[package]] name = "gix-commitgraph" -version = "0.27.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043cbe49b7a7505150db975f3cb7c15833335ac1e26781f615454d9d640a28fe" +checksum = "a2cd7f054ae2727223fe46dd39c012f066b12f532962d336d29ee193261787da" dependencies = [ "bstr", "gix-chunk", - "gix-hash 0.17.0", + "gix-error", + "gix-hash", "memmap2", - "thiserror 2.0.18", + "nonempty", ] [[package]] name = "gix-config" -version = "0.44.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6f830bf746604940261b49abf7f655d2c19cadc9f4142ae9379e3a316e8cfa" +checksum = "103d11bef95c467577ecfa8b7b86a22e65af3507b2c9bfa3809a4afbae7df301" dependencies = [ "bstr", "gix-config-value", - "gix-features 0.41.1", + "gix-features", "gix-glob", "gix-path", "gix-ref", "gix-sec", - "memchr", - "once_cell", + "gix-utils", "smallvec", "thiserror 2.0.18", "unicode-bom", - "winnow 0.7.15", ] [[package]] name = "gix-config-value" -version = "0.14.12" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dc2c844c4cf141884678cabef736fd91dd73068b9146e6f004ba1a0457944b6" +checksum = "6f6af5321bfd3711a279d6b244d58532ba1cfabf9eb6374791f19929d8970082" dependencies = [ "bitflags 2.11.0", "bstr", @@ -2546,30 +2569,50 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "gix-credentials" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbdb1c417980d05d547c19fc2b63344b5257c2387048d69ffe957bda142b59" +dependencies = [ + "bstr", + "gix-command", + "gix-config-value", + "gix-date", + "gix-path", + "gix-prompt", + "gix-quote", + "gix-sec", + "gix-trace", + "gix-url", + "thiserror 2.0.18", +] + [[package]] name = "gix-date" -version = "0.9.4" +version = "0.15.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa30058ec7d3511fbc229e4f9e696a35abd07ec5b82e635eff864a2726217e4" +checksum = "7e47b9e8cdc688296609b706428de570f88b1e0eed7156dde7b4a89d26fa4567" dependencies = [ "bstr", + "gix-error", "itoa", "jiff", - "thiserror 2.0.18", ] [[package]] name = "gix-diff" -version = "0.51.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c975dad2afc85e4e233f444d1efbe436c3cdcf3a07173984509c436d00a3f8" +checksum = "fee7d89a3c507491cdfc57a1d1e0e300214720b4f7709ebc253e422f99822bfc" dependencies = [ "bstr", "gix-attributes", "gix-command", "gix-filter", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-fs", + "gix-hash", + "gix-imara-diff", "gix-index", "gix-object", "gix-path", @@ -2578,40 +2621,38 @@ dependencies = [ "gix-trace", "gix-traverse", "gix-worktree", - "imara-diff", "thiserror 2.0.18", ] [[package]] name = "gix-dir" -version = "0.13.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5879497bd3815d8277ed864ec8975290a70de5b62bb92d2d666a4cefc5d4793b" +checksum = "f24bc78f283946ac64757c8a61ffa71f0230aa1e8d98cbb0771db479871dd5b6" dependencies = [ "bstr", "gix-discover", - "gix-fs 0.14.0", + "gix-fs", "gix-ignore", "gix-index", "gix-object", "gix-path", "gix-pathspec", "gix-trace", - "gix-utils 0.2.0", + "gix-utils", "gix-worktree", "thiserror 2.0.18", ] [[package]] name = "gix-discover" -version = "0.39.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fb8a4349b854506a3915de18d3341e5f1daa6b489c8affc9ca0d69efe86781" +checksum = "b9f517766fa1101dfe2606c1a19a8ffa699099030995a9194445446dfe261bdf" dependencies = [ "bstr", "dunce", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-fs", "gix-path", "gix-ref", "gix-sec", @@ -2619,136 +2660,107 @@ dependencies = [ ] [[package]] -name = "gix-features" -version = "0.41.1" +name = "gix-error" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016d6050219458d14520fe22bdfdeb9cb71631dec9bc2724767c983f60109634" +checksum = "4a9292309fd944e71b2a3c96d3c03a6feb8852db646febdde7cbb9f79cb5f329" dependencies = [ - "crc32fast", - "flate2", - "gix-path", - "gix-trace", - "gix-utils 0.2.0", - "libc", - "once_cell", - "prodash", - "thiserror 2.0.18", - "walkdir", + "bstr", ] [[package]] name = "gix-features" -version = "0.42.1" +version = "0.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f4399af6ec4fd9db84dd4cf9656c5c785ab492ab40a7c27ea92b4241923fed" +checksum = "20aa09e83a48dc02c5f5f08578aa79d3ab1bab4618b8c362f88684645a02bdcc" dependencies = [ + "bytes", + "crc32fast", + "crossbeam-channel", + "gix-path", "gix-trace", - "gix-utils 0.3.1", + "gix-utils", "libc", + "once_cell", + "parking_lot", "prodash", + "walkdir", ] [[package]] name = "gix-filter" -version = "0.18.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb2b2bbffdc5cc9b2b82fc82da1b98163c9b423ac2b45348baa83a947ac9ab89" +checksum = "5e7b5dbf524d97e839f642930c76d7f011c0791e7d11d8148989ac5af7c76aa8" dependencies = [ "bstr", "encoding_rs", "gix-attributes", "gix-command", - "gix-hash 0.17.0", + "gix-hash", "gix-object", - "gix-packetline-blocking", + "gix-packetline", "gix-path", "gix-quote", "gix-trace", - "gix-utils 0.2.0", + "gix-utils", "smallvec", "thiserror 2.0.18", ] [[package]] name = "gix-fs" -version = "0.14.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "951e886120dc5fa8cac053e5e5c89443f12368ca36811b2e43d1539081f9c111" +checksum = "865cf13fcaf5455220546cb9607c416bd1be9a6caafd143655a362fdeab64e80" dependencies = [ "bstr", - "fastrand", - "gix-features 0.41.1", + "gix-features", "gix-path", - "gix-utils 0.2.0", - "thiserror 2.0.18", -] - -[[package]] -name = "gix-fs" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a0637149b4ef24d3ea55f81f77231401c8463fae6da27331c987957eb597c7" -dependencies = [ - "bstr", - "fastrand", - "gix-features 0.42.1", - "gix-path", - "gix-utils 0.3.1", + "gix-utils", "thiserror 2.0.18", ] [[package]] name = "gix-glob" -version = "0.19.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20972499c03473e773a2099e5fd0c695b9b72465837797a51a43391a1635a030" +checksum = "421e92a711554fa5827d1b0599d3389acdd0f6729e97a8c5a57d79af1e50bf36" dependencies = [ "bitflags 2.11.0", "bstr", - "gix-features 0.41.1", + "gix-features", "gix-path", ] [[package]] name = "gix-hash" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "834e79722063958b03342edaa1e17595cd2939bb2b3306b3225d0815566dcb49" -dependencies = [ - "faster-hex 0.9.0", - "gix-features 0.41.1", - "sha1-checked", - "thiserror 2.0.18", -] - -[[package]] -name = "gix-hash" -version = "0.18.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d4900562c662852a6b42e2ef03442eccebf24f047d8eab4f23bc12ef0d785d8" +checksum = "13adaa73415fd6c902310923f68d0b98e8cecf14b33ea58c02cc387cee56f54e" dependencies = [ - "faster-hex 0.10.0", - "gix-features 0.42.1", + "faster-hex", + "gix-features", "sha1-checked", "thiserror 2.0.18", ] [[package]] name = "gix-hashtable" -version = "0.8.1" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b5cb3c308b4144f2612ff64e32130e641279fcf1a84d8d40dad843b4f64904" +checksum = "78fccd6fea3bcf0b39c076bae60ae49b08daaf538b950202101a981f9d3c01d3" dependencies = [ - "gix-hash 0.18.0", - "hashbrown 0.14.5", + "gix-hash", + "hashbrown 0.17.1", "parking_lot", ] [[package]] name = "gix-ignore" -version = "0.14.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a27c8380f493a10d1457f756a3f81924d578fc08d6535e304dfcafbf0261d18" +checksum = "12cff8e8aa125e39377456073e63df3334d9e5741372ddcc226198015076dda2" dependencies = [ "bstr", "gix-glob", @@ -2757,82 +2769,105 @@ dependencies = [ "unicode-bom", ] +[[package]] +name = "gix-imara-diff" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a791e6620676a875f362f3156ed213e73ca099a09bf992c18812abe65cc37b1" +dependencies = [ + "bstr", + "hashbrown 0.16.1", +] + [[package]] name = "gix-index" -version = "0.39.0" +version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "855bece2d4153453aa5d0a80d51deea1ce8cd6a3b4cf213da85ac344ccb908a7" +checksum = "5009c4e7e9f9b4cfaaab1153e49133eb04d79c015b5702d6c3d2ab94271a89c6" dependencies = [ "bitflags 2.11.0", "bstr", "filetime", "fnv", "gix-bitmap", - "gix-features 0.41.1", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-features", + "gix-fs", + "gix-hash", "gix-lock", "gix-object", "gix-traverse", - "gix-utils 0.2.0", - "gix-validate 0.9.4", - "hashbrown 0.14.5", + "gix-utils", + "gix-validate", + "hashbrown 0.17.1", "itoa", "libc", "memmap2", - "rustix 0.38.44", + "rustix 1.1.4", "smallvec", "thiserror 2.0.18", ] [[package]] name = "gix-lock" -version = "17.1.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570f8b034659f256366dc90f1a24924902f20acccd6a15be96d44d1269e7a796" +checksum = "d4c69157820343bf1c6e4b88b9808e920900de02e18aaf5862b30ada43814848" dependencies = [ "gix-tempfile", - "gix-utils 0.3.1", + "gix-utils", "thiserror 2.0.18", ] +[[package]] +name = "gix-negotiate" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fa5aa789990f124e4f559b142cecfb60662cb4ae17006684ea9d668f4f07689" +dependencies = [ + "bitflags 2.11.0", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-object", + "gix-revwalk", +] + [[package]] name = "gix-object" -version = "0.48.0" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4943fcdae6ffc135920c9ea71e0362ed539182924ab7a85dd9dac8d89b0dd69a" +checksum = "0e48c235e7f886eb819fc878af75be889333dd3c38bee02ed7af48ae2cf596c4" dependencies = [ "bstr", "gix-actor", "gix-date", - "gix-features 0.41.1", - "gix-hash 0.17.0", + "gix-features", + "gix-hash", "gix-hashtable", - "gix-path", - "gix-utils 0.2.0", - "gix-validate 0.9.4", + "gix-utils", + "gix-validate", "itoa", "smallvec", "thiserror 2.0.18", - "winnow 0.7.15", ] [[package]] name = "gix-odb" -version = "0.68.0" +version = "0.83.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50306d40dcc982eb6b7593103f066ea6289c7b094cb9db14f3cd2be0b9f5e610" +checksum = "8dd494ffb5037e62b8220109e894d2861ff2150a2cacbfccdba57ae1ebab2b96" dependencies = [ "arc-swap", - "gix-date", - "gix-features 0.41.1", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-features", + "gix-fs", + "gix-hash", "gix-hashtable", "gix-object", "gix-pack", "gix-path", "gix-quote", + "gix-zlib", + "memmap2", "parking_lot", "tempfile", "thiserror 2.0.18", @@ -2840,63 +2875,55 @@ dependencies = [ [[package]] name = "gix-pack" -version = "0.58.0" +version = "0.73.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b65fffb09393c26624ca408d32cfe8776fb94cd0a5cdf984905e1d2f39779cb" +checksum = "6d5446127b269706e85998065267ddd2ccc3550179da6780b22fe496175ccb20" dependencies = [ "clru", "gix-chunk", - "gix-features 0.41.1", - "gix-hash 0.17.0", + "gix-error", + "gix-features", + "gix-hash", "gix-hashtable", "gix-object", "gix-path", + "gix-tempfile", + "gix-zlib", "memmap2", + "parking_lot", "smallvec", "thiserror 2.0.18", ] [[package]] name = "gix-packetline" -version = "0.18.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123844a70cf4d5352441dc06bab0da8aef61be94ec239cb631e0ba01dc6d3a04" -dependencies = [ - "bstr", - "faster-hex 0.9.0", - "gix-trace", - "thiserror 2.0.18", -] - -[[package]] -name = "gix-packetline-blocking" -version = "0.18.3" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecf3ea2e105c7e45587bac04099824301262a6c43357fad5205da36dbb233b3" +checksum = "3766025c72319c4accdd854a18e6f0dd176c8eb0f3bc8a60a7765be2b50cabf2" dependencies = [ "bstr", - "faster-hex 0.9.0", + "faster-hex", "gix-trace", "thiserror 2.0.18", ] [[package]] name = "gix-path" -version = "0.10.22" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb06c3e4f8eed6e24fd915fa93145e28a511f4ea0e768bae16673e05ed3f366" +checksum = "751d6bd162106f8c1e7e9aaccb5bbdd605267e91a930a17a4560c46e33a9100c" dependencies = [ "bstr", "gix-trace", - "gix-validate 0.10.1", + "gix-validate", "thiserror 2.0.18", ] [[package]] name = "gix-pathspec" -version = "0.10.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8422c3c9066d649074b24025125963f85232bfad32d6d16aea9453b82ec14" +checksum = "49f6fa5f8007f008187c3f60b4373209ca83d1cc947f35ede03e16cd15a4d137" dependencies = [ "bitflags 2.11.0", "bstr", @@ -2907,98 +2934,121 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "gix-prompt" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb1f1eb92d6f4c9d4c105a6ca912cff637fbd5cacbcbafa5deccd88bfaa3565" +dependencies = [ + "gix-command", + "gix-config-value", + "parking_lot", + "rustix 1.1.4", + "thiserror 2.0.18", +] + [[package]] name = "gix-protocol" -version = "0.49.0" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5678ddae1d62880bc30e2200be1b9387af3372e0e88e21f81b4e7f8367355b5a" +checksum = "dede40e89c1e90f548415f50636bb051f6d9c60f68b8b710bc07825722d19588" dependencies = [ + "bisync", "bstr", + "gix-credentials", "gix-date", - "gix-features 0.41.1", - "gix-hash 0.17.0", + "gix-features", + "gix-hash", + "gix-lock", + "gix-negotiate", + "gix-object", "gix-ref", + "gix-refspec", + "gix-revwalk", "gix-shallow", + "gix-trace", "gix-transport", - "gix-utils 0.2.0", - "maybe-async", + "gix-utils", + "nonempty", "thiserror 2.0.18", - "winnow 0.7.15", ] [[package]] name = "gix-quote" -version = "0.5.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b005c550bf84de3b24aa5e540a23e6146a1c01c7d30470e35d75a12f827f969" +checksum = "a6e541fc33cc2b783b7979040d445a0c86a2eca747c8faea4ca84230d06ae6ef" dependencies = [ "bstr", - "gix-utils 0.2.0", - "thiserror 2.0.18", + "gix-error", + "gix-utils", ] [[package]] name = "gix-ref" -version = "0.51.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e1f7eb6b7ce82d2d19961f74bd637bab3ea79b1bc7bfb23dbefc67b0415d8b" +checksum = "eeb0c90a8f6202ceaaa22996cbf837c943ccb2d8af9ff3490f0758305e6b7883" dependencies = [ "gix-actor", - "gix-features 0.41.1", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-features", + "gix-fs", + "gix-hash", "gix-lock", "gix-object", "gix-path", "gix-tempfile", - "gix-utils 0.2.0", - "gix-validate 0.9.4", + "gix-utils", + "gix-validate", "memmap2", "thiserror 2.0.18", - "winnow 0.7.15", ] [[package]] name = "gix-refspec" -version = "0.29.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8587b21e2264a6e8938d940c5c99662779c13a10741a5737b15fc85c252ffc" +checksum = "7406282cc0259b51f6aee299ca3d31279a020530363152a2e6c96e8a7f7bbc83" dependencies = [ "bstr", - "gix-hash 0.17.0", + "gix-error", + "gix-glob", + "gix-hash", "gix-revision", - "gix-validate 0.9.4", + "gix-validate", "smallvec", "thiserror 2.0.18", ] [[package]] name = "gix-revision" -version = "0.33.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342caa4e158df3020cadf62f656307c3948fe4eacfdf67171d7212811860c3e9" +checksum = "e55e09d4a1ecf2beecc8c09cafcad37979e805b31f588b0e957e191df5783681" dependencies = [ "bitflags 2.11.0", "bstr", "gix-commitgraph", "gix-date", - "gix-hash 0.17.0", + "gix-error", + "gix-hash", "gix-hashtable", "gix-object", "gix-revwalk", "gix-trace", - "thiserror 2.0.18", + "nonempty", ] [[package]] name = "gix-revwalk" -version = "0.19.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dc7c3d7e5cdc1ab8d35130106e4af0a4f9f9eca0c81f4312b690780e92bde0d" +checksum = "36c113c0a53294dc6280ffc06cbcc4f50f820397e97d6a00b429a44b8db26e29" dependencies = [ "gix-commitgraph", "gix-date", - "gix-hash 0.17.0", + "gix-error", + "gix-hash", "gix-hashtable", "gix-object", "smallvec", @@ -3007,56 +3057,59 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.12" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aeb0f13de9ef2f3033f5ff218de30f44db827ac9f1286f9ef050aacddd5888" +checksum = "af4fe6c152c1d50aea36f299825702cd37e303307832fec1d0fdd5844e47ce2f" dependencies = [ "bitflags 2.11.0", "gix-path", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "gix-shallow" -version = "0.3.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc0598aacfe1d52575a21c9492fee086edbb21e228ec36c819c42ab923f434c3" +checksum = "1ecc9f4b40537043e4bbd7d3d1760e74fb8e7b07a546166b558acaa73ad97f4a" dependencies = [ "bstr", - "gix-hash 0.17.0", + "gix-hash", "gix-lock", + "nonempty", "thiserror 2.0.18", ] [[package]] name = "gix-status" -version = "0.18.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605a6d0eb5891680c46e24b2ee7a63ef7bd39cb136dc7c7e55172960cf68b2f5" +checksum = "5f83b1c74e69b90411fbfe89ccebc47aa49457ce4eb9b942b1311258fc863d22" dependencies = [ "bstr", "filetime", "gix-diff", "gix-dir", - "gix-features 0.41.1", + "gix-features", "gix-filter", - "gix-fs 0.14.0", - "gix-hash 0.17.0", + "gix-fs", + "gix-hash", "gix-index", "gix-object", "gix-path", "gix-pathspec", "gix-worktree", + "hashbrown 0.16.1", "portable-atomic", "thiserror 2.0.18", + "windows-sys 0.61.2", ] [[package]] name = "gix-submodule" -version = "0.18.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c7390c2059505c365e9548016d4edc9f35749c6a9112b7b1214400bbc68da2" +checksum = "5fd98077a56d08886112e6b08dc94076d03539f4bc0b9d7880e4be2b8a640d8c" dependencies = [ "bstr", "gix-config", @@ -3069,36 +3122,36 @@ dependencies = [ [[package]] name = "gix-tempfile" -version = "17.1.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c750e8c008453a2dba67a2b0d928b7716e05da31173a3f5e351d5457ad4470aa" +checksum = "b675b920bd5a61d17ad542772f03ec34c60feb8ff683e1560c03ae967363731e" dependencies = [ "dashmap", - "gix-fs 0.15.0", + "gix-fs", "libc", - "once_cell", "parking_lot", - "signal-hook", + "signal-hook 0.4.4", "signal-hook-registry", "tempfile", ] [[package]] name = "gix-trace" -version = "0.1.18" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f69a13643b8437d4ca6845e08143e847a36ca82903eed13303475d0ae8b162e0" +checksum = "be3eb81d9dc914335923e50d52829c551feefd6a72d176c4130c546b67a60814" [[package]] name = "gix-transport" -version = "0.46.0" +version = "0.58.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3f68c2870bfca8278389d2484a7f2215b67d0b0cc5277d3c72ad72acf41787e" +checksum = "3f36d045b840f8aeee1a527e677eab1fbebfbbe94bf2e708fa81d0b4b742d5fc" dependencies = [ "bstr", "gix-command", - "gix-features 0.41.1", + "gix-features", "gix-packetline", + "gix-path", "gix-quote", "gix-sec", "gix-url", @@ -3107,14 +3160,14 @@ dependencies = [ [[package]] name = "gix-traverse" -version = "0.45.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c0b049f8bdb61b20016694102f7b507f2e1727e83e9c5e6dad4f7d84ff7384" +checksum = "008c5cd879e46e86b5c2469e633611978b18775d53d05668d691bc13088bd409" dependencies = [ "bitflags 2.11.0", "gix-commitgraph", "gix-date", - "gix-hash 0.17.0", + "gix-hash", "gix-hashtable", "gix-object", "gix-revwalk", @@ -3124,76 +3177,100 @@ dependencies = [ [[package]] name = "gix-url" -version = "0.30.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dfe23f93f1ddb84977d80bb0dd7aa09d1bf5d5afc0c9b6820cccacc25ae860" +checksum = "31bdfc93aa880cda3272718a5879ce3aa7723fa13514320dd6608151607afe72" dependencies = [ "bstr", - "gix-features 0.41.1", "gix-path", + "gix-utils", "percent-encoding 2.3.2", "thiserror 2.0.18", - "url 2.5.8", ] [[package]] name = "gix-utils" -version = "0.2.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189f8724cf903e7fd57cfe0b7bc209db255cacdcb22c781a022f52c3a774f8d0" +checksum = "b1795bd2a970ca8b2185318c2abb97d955c71992f1cf28de73ad3b593a9f3ce8" dependencies = [ "bstr", "fastrand", + "getrandom 0.4.2", "unicode-normalization", ] [[package]] -name = "gix-utils" -version = "0.3.1" +name = "gix-validate" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "befcdbdfb1238d2854591f760a48711bed85e72d80a10e8f2f93f656746ef7c5" +checksum = "9a034e84d1e04e1b1f20f51f12491da230b6ac8b925d0c8e1b89bcd87a7c5ccc" dependencies = [ - "fastrand", - "unicode-normalization", + "bstr", ] [[package]] -name = "gix-validate" -version = "0.9.4" +name = "gix-worktree" +version = "0.55.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34b5f1253109da6c79ed7cf6e1e38437080bb6d704c76af14c93e2f255234084" +checksum = "31eb8e675122e83585e461fe28f68ff8c5ed55b49017b697e7e76423ff973424" dependencies = [ "bstr", - "thiserror 2.0.18", + "gix-attributes", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-validate", ] [[package]] -name = "gix-validate" -version = "0.10.1" +name = "gix-worktree-state" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1e63a5b516e970a594f870ed4571a8fdcb8a344e7bd407a20db8bd61dbfde4" +checksum = "bc47372fc12b9fbea51b257bcc8d4970326cf5c7e42135bbfb5d72871bb30bd4" dependencies = [ "bstr", + "gix-features", + "gix-filter", + "gix-fs", + "gix-index", + "gix-object", + "gix-path", + "gix-worktree", + "io-close", "thiserror 2.0.18", ] [[package]] -name = "gix-worktree" -version = "0.40.0" +name = "gix-worktree-stream" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7760dbc4b79aa274fed30adc0d41dca6b917641f26e7867c4071b1fb4dc727b" +checksum = "3b088c8724e7be120c4798dd86925cf05332c9d356a463542578600c50c7a549" dependencies = [ - "bstr", "gix-attributes", - "gix-features 0.41.1", - "gix-fs 0.14.0", - "gix-glob", - "gix-hash 0.17.0", - "gix-ignore", - "gix-index", + "gix-error", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", "gix-object", "gix-path", - "gix-validate 0.9.4", + "gix-traverse", + "parking_lot", +] + +[[package]] +name = "gix-zlib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e8813f5579b3075ff9c90f7c59cd2b62b4ebb639361f0911648b22d7446cc7c" +dependencies = [ + "thiserror 2.0.18", + "zlib-rs", ] [[package]] @@ -3285,7 +3362,7 @@ dependencies = [ "prost-types", "rand 0.8.5", "reqwest 0.11.27", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "serde", "serde_json", "serde_path_to_error", @@ -3293,7 +3370,7 @@ dependencies = [ "superposition_core", "tempfile", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tokio", "tokio-stream", "tonic 0.14.5", @@ -3408,6 +3485,17 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] + [[package]] name = "hashlink" version = "0.8.4" @@ -3799,7 +3887,7 @@ dependencies = [ "serde", "serde_json", "subtle", - "time 0.3.47", + "time 0.3.55", "url 2.5.8", "zeroize", ] @@ -3966,15 +4054,6 @@ dependencies = [ "png", ] -[[package]] -name = "imara-diff" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d34b7d42178945f775e84bc4c36dde7c1c6cdfea656d3354d009056f2bb3d2" -dependencies = [ - "hashbrown 0.15.5", -] - [[package]] name = "impl-more" version = "0.1.9" @@ -4100,7 +4179,7 @@ dependencies = [ "serde_json", "strum 0.26.3", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tracing", "tracing-actix-web", "ucs_common_enums", @@ -4108,6 +4187,16 @@ dependencies = [ "utoipa", ] +[[package]] +name = "io-close" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "ipnet" version = "2.12.0" @@ -4181,25 +4270,37 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ + "defmt", + "jiff-core", "jiff-static", "jiff-tzdb-platform", "log 0.4.29", "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", ] [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", "syn 2.0.117", @@ -4245,7 +4346,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", ] [[package]] @@ -4294,7 +4395,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "time 0.3.47", + "time 0.3.55", "url 2.5.8", "uuid", ] @@ -4346,15 +4447,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "kstring" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" -dependencies = [ - "static_assertions", -] - [[package]] name = "language-tags" version = "0.2.2" @@ -4384,9 +4476,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -4394,18 +4486,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" -[[package]] -name = "libredox" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" -dependencies = [ - "bitflags 2.11.0", - "libc", - "plain", - "redox_syscall 0.7.3", -] - [[package]] name = "libz-sys" version = "1.1.25" @@ -4490,14 +4570,14 @@ dependencies = [ [[package]] name = "log_utils" version = "0.1.0" -source = "git+https://github.com/juspay/framework-libs-rs?rev=243562041252fe5897ce888d20b715ffdc3767ce#243562041252fe5897ce888d20b715ffdc3767ce" +source = "git+https://github.com/juspay/framework-libs-rs?rev=76613f5d0c72fd3d26a3403ae859c2a7545e8dd2#76613f5d0c72fd3d26a3403ae859c2a7545e8dd2" dependencies = [ "gethostname 1.1.0", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "serde", "serde_json", "thiserror 2.0.18", - "time 0.3.47", + "time 0.3.55", "tracing", "tracing-appender", "tracing-subscriber", @@ -4571,17 +4651,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" -[[package]] -name = "maybe-async" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "md5" version = "0.7.0" @@ -4596,9 +4665,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -4821,13 +4890,19 @@ dependencies = [ "memchr", ] +[[package]] +name = "nonempty" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9737e026353e5cd0736f98eddae28665118eb6f6600902a7f50db585621fecb6" + [[package]] name = "nu-ansi-term" version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4887,9 +4962,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -5177,7 +5252,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -5615,11 +5690,10 @@ dependencies = [ [[package]] name = "prodash" -version = "29.0.2" +version = "31.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04bb108f648884c23b98a0e940ebc2c93c0c3b89f04dbaf7eb8256ce617d1bc" +checksum = "962200e2d7d551451297d9fdce85138374019ada198e30ea9ede38034e27604c" dependencies = [ - "log 0.4.29", "parking_lot", ] @@ -5683,7 +5757,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "itertools 0.14.0", "log 0.4.29", "multimap", @@ -5830,7 +5904,7 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "rustls 0.23.37", "socket2 0.6.3", "thiserror 2.0.18", @@ -5850,7 +5924,7 @@ dependencies = [ "lru-slab", "rand 0.9.2", "ring", - "rustc-hash 2.1.1", + "rustc-hash 2.1.3", "rustls 0.23.37", "rustls-pki-types", "slab", @@ -6143,15 +6217,6 @@ dependencies = [ "bitflags 2.11.0", ] -[[package]] -name = "redox_syscall" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" -dependencies = [ - "bitflags 2.11.0", -] - [[package]] name = "ref-cast" version = "1.0.25" @@ -6416,7 +6481,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "strum 0.26.3", - "time 0.3.47", + "time 0.3.55", "tokio", "tracing", "tracing-actix-web", @@ -6489,9 +6554,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -6525,7 +6590,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -6596,9 +6661,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "rusty-fork" @@ -6878,7 +6943,7 @@ dependencies = [ "serde_core", "serde_json", "serde_with_macros", - "time 0.3.47", + "time 0.3.55", ] [[package]] @@ -7000,6 +7065,16 @@ dependencies = [ "signal-hook-registry", ] +[[package]] +name = "signal-hook" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a0c28ca5908dbdbcd52e6fdaa00358ab88637f8ab33e1f188dd510eb44b53d" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-mio" version = "0.2.5" @@ -7008,7 +7083,7 @@ checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", "mio 0.8.11", - "signal-hook", + "signal-hook 0.3.18", ] [[package]] @@ -7052,7 +7127,7 @@ dependencies = [ "num-bigint", "num-traits", "thiserror 2.0.18", - "time 0.3.47", + "time 0.3.55", ] [[package]] @@ -7130,7 +7205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -7398,6 +7473,12 @@ dependencies = [ "sval_nested", ] +[[package]] +name = "symlink" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" + [[package]] name = "syn" version = "1.0.109" @@ -7504,7 +7585,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -7598,12 +7679,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "libc", "num-conv", "num_threads", @@ -7615,15 +7695,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -8051,13 +8131,14 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" +checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c" dependencies = [ "crossbeam-channel", + "symlink", "thiserror 2.0.18", - "time 0.3.47", + "time 0.3.55", "tracing-subscriber", ] @@ -8222,7 +8303,7 @@ dependencies = [ "serde", "serde_json", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "ucs_common_utils", ] @@ -8253,6 +8334,7 @@ dependencies = [ "http 1.4.0", "hyperswitch_masking", "josekit", + "log_utils", "md5", "multipart", "nanoid", @@ -8273,7 +8355,7 @@ dependencies = [ "superposition_core", "superposition_types", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tonic 0.14.5", "tracing", "tracing-kafka", @@ -8308,7 +8390,7 @@ dependencies = [ "serde_path_to_error", "strum 0.26.3", "thiserror 1.0.69", - "time 0.3.47", + "time 0.3.55", "tokio", "tonic 0.14.5", "tonic-reflection", @@ -8711,43 +8793,41 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vergen" -version = "9.0.6" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2bf58be11fc9414104c6d3a2e464163db5ef74b12296bda593cac37b6e4777" +checksum = "3fd02b50246a773d6b8f48cf8e4e623a2773fd31cbe697bf10289abbb17e9e87" dependencies = [ "anyhow", - "cargo_metadata 0.19.2", - "derive_builder", - "regex", + "bon", "rustc_version", "rustversion", - "time 0.3.47", + "time 0.3.55", "vergen-lib", ] [[package]] name = "vergen-gix" -version = "1.0.9" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f8dfe6eb333a1397e596164ae7326f68e4b95267b41aedc6aa3c81f3426a010" +checksum = "3a3a1d6008b29a3163c509b206109fea7e79cb8de43ef1468b7d3c29471f3751" dependencies = [ "anyhow", - "derive_builder", + "bon", "gix", "rustversion", - "time 0.3.47", + "time 0.3.55", "vergen", "vergen-lib", ] [[package]] name = "vergen-lib" -version = "0.1.6" +version = "10.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b07e6010c0f3e59fcb164e0163834597da68d1f864e2b8ca49f74de01e9c166" +checksum = "7d6a4e23de0fd3f8a940650a4d83eca980e9ef8f108fe6ddeb5313b0313523d3" dependencies = [ "anyhow", - "derive_builder", + "bon", "rustversion", ] @@ -8993,7 +9073,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] @@ -9557,6 +9637,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "zlib-rs" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12" + [[package]] name = "zmij" version = "1.0.21" diff --git a/Dockerfile b/Dockerfile index 9ea7e4a5e5..78e9de4b9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,7 +44,7 @@ ENV SCCACHE_CACHE_SIZE=5G # Cook dependencies using cargo-chef with caching RUN --mount=type=cache,target=/sccache \ - cargo chef cook --release --features kafka,connector-request-kafka,otel --recipe-path recipe.json + cargo chef cook --release --features kafka,connector-request-kafka,otel,log-transformations --recipe-path recipe.json # Install additional build-time dependencies RUN apt-get update \ @@ -57,7 +57,7 @@ RUN apt-get update \ # Build only the binary shipped by the runtime stage; skips test/SDK crates. COPY . . RUN --mount=type=cache,target=/sccache \ - cargo build --release --features kafka,connector-request-kafka,otel -p grpc-server + cargo build --release --features kafka,connector-request-kafka,otel,log-transformations -p grpc-server # Output sccache statistics RUN sccache --show-stats diff --git a/crates/common/common_utils/Cargo.toml b/crates/common/common_utils/Cargo.toml index f4608e8f33..395e115e68 100644 --- a/crates/common/common_utils/Cargo.toml +++ b/crates/common/common_utils/Cargo.toml @@ -12,6 +12,7 @@ anyhow = "1.0" rdkafka = { version = "0.36", optional = true } tracing-kafka = { path = "../tracing-kafka", optional = true } tracing = { workspace = true } +log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "log_utils", features = ["tracing", "tracing-storage-api"] } once_cell = "1.19" chrono = "0.4.31" @@ -52,6 +53,7 @@ default = [] kafka = ["dep:rdkafka", "dep:tracing-kafka"] async_ext = ["dep:async-trait", "dep:futures"] superposition = ["dep:superposition_core", "dep:superposition_types"] +log-transformations = [] [dependencies.async-trait] version = "0.1.74" diff --git a/crates/common/common_utils/src/events.rs b/crates/common/common_utils/src/events.rs index e9bc9c1a5f..05d33c8b10 100644 --- a/crates/common/common_utils/src/events.rs +++ b/crates/common/common_utils/src/events.rs @@ -1,6 +1,9 @@ +#[cfg(feature = "log-transformations")] +use std::borrow::Cow; +use std::collections::HashMap; + use hyperswitch_masking::ErasedMaskSerialize; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; use crate::errors::EventPublisherError; use crate::types::ExecutionMode; @@ -474,6 +477,249 @@ pub struct KafkaTopicConfig { pub partition_key_field: String, } +/// Controls whether transformations copy or replace the original source fields. +#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum TransformationMode { + /// Add the new key but keep the original source field (default). + #[default] + Copy, + /// Add the new key and remove the original source field after all transformations complete. + Replace, +} + +/// A single field entry for golden log lines. +/// +/// Each entry is either a literal value or a reference to a span storage field. +/// - `{ value = "literal" }` — injects a constant string. +/// - `{ source = "span_field" }` — reads the value from the named span storage field at runtime. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[serde(untagged)] +pub enum LogFieldEntry { + /// Read value from the named field in span storage. + Source { source: String }, + /// Use a literal string value. + Value { value: String }, +} + +/// A single compiled log field with pre-split target path segments. +#[derive(Debug, Clone)] +pub struct CompiledLogField { + /// Pre-split target path segments (e.g., `["api_details", "url"]`). + /// Segment 0 is the root key; segments 1.. are the nested sub-path. + pub target_segments: Vec, + /// Top-level key — segment 0 of the target path. + pub target_root_key: String, + /// Resolved entry: either a source field name or a literal value. + pub entry: CompiledFieldEntry, +} + +/// Resolved field entry — either a source field reference or a literal value. +#[derive(Debug, Clone)] +pub enum CompiledFieldEntry { + /// Read value from this field name in span storage at runtime. + Source(String), + /// Use this literal value. + Value(serde_json::Value), +} + +/// Pre-compiled fields for one golden log line type (incoming or outgoing). +#[derive(Debug, Clone, Default)] +pub struct CompiledLogFields { + pub rules: Vec, +} + +impl CompiledLogFields { + /// Compile raw `target_path → LogFieldEntry` mappings into pre-split rules. + pub fn compile(raw: &HashMap) -> Self { + let rules = raw + .iter() + .filter_map(|(target_path, field_entry)| { + let segments: Vec = target_path.split('.').map(String::from).collect(); + let root_key = segments.first()?.clone(); + let entry = match field_entry { + LogFieldEntry::Source { source } => CompiledFieldEntry::Source(source.clone()), + LogFieldEntry::Value { value } => { + CompiledFieldEntry::Value(serde_json::Value::String(value.clone())) + } + }; + Some(CompiledLogField { + target_segments: segments, + target_root_key: root_key, + entry, + }) + }) + .collect(); + Self { rules } + } + + /// Returns `true` if no field rules are configured. + pub fn is_empty(&self) -> bool { + self.rules.is_empty() + } +} + +/// Holds compiled fields for both golden log lines. +#[derive(Debug, Clone, Default)] +pub struct CompiledLogFieldsConfig { + /// Runtime kill-switch: when `false`, `apply_log_fields` is skipped even + /// though the `log-transformations` feature is compiled in. + pub enabled: bool, + pub incoming: CompiledLogFields, + pub outgoing: CompiledLogFields, +} + +impl CompiledLogFieldsConfig { + pub fn compile( + enabled: bool, + incoming: &HashMap, + outgoing: &HashMap, + ) -> Self { + Self { + enabled, + incoming: CompiledLogFields::compile(incoming), + outgoing: CompiledLogFields::compile(outgoing), + } + } +} + +/// Apply compiled log field rules to the current span's storage. +/// +/// For each rule: +/// - `Source` entries read a value from the span storage snapshot. +/// - `Value` entries use the literal value directly. +/// +/// Dotted target paths build nested JSON objects. When writing a nested object, +/// it is deep-merged with any existing value for the same root key in the span. +#[cfg(feature = "log-transformations")] +pub fn apply_log_fields(compiled: &CompiledLogFields) { + if compiled.is_empty() { + return; + } + + // Snapshot span storage (needed for Source entries to read current values). + let snapshot: Option, serde_json::Value>> = + log_utils::Storage::with_current_span(|storage| storage.values().clone()); + + // Build writes: for each rule, resolve the value and group by root key. + let mut writes: HashMap = HashMap::new(); + for rule in &compiled.rules { + let resolved_value = match &rule.entry { + CompiledFieldEntry::Value(v) => v.clone(), + CompiledFieldEntry::Source(field) => { + match snapshot + .as_ref() + .and_then(|s| s.get(field.as_str())) + .cloned() + { + Some(v) => v, + None => continue, // source field not present in span, skip + } + } + }; + + if rule.target_segments.len() == 1 { + // Flat key: "connector" = { source = "gateway" } + writes.insert(rule.target_root_key.clone(), resolved_value); + } else { + // Nested target: "api_details.url" = { source = "request.url" } + let root = writes + .entry(rule.target_root_key.clone()) + .or_insert_with(|| serde_json::json!({})); + if let Some(rest) = rule.target_segments.get(1..) { + set_nested_value_from_segments(root, rest, resolved_value); + } + } + } + + // Filter out reserved keys BEFORE entering the span lock. + // `record_value` calls `tracing::warn!` for reserved keys, which re-enters + // the subscriber and deadlocks when called inside `with_current_span_mut`. + let writes: Vec<_> = writes + .into_iter() + .filter(|(key, _)| { + if log_utils::Storage::is_reserved(key) { + tracing::warn!( + "Log field target key `{key}` is reserved by the logging infrastructure, skipping" + ); + false + } else { + true + } + }) + .collect(); + + if writes.is_empty() { + return; + } + + // Write to span storage, deep-merging nested objects with existing values. + log_utils::Storage::with_current_span_mut(|storage| { + for (key, value) in writes { + if value.is_object() { + // Deep-merge with existing object if present + if let Some(existing) = storage.values().get(key.as_str()).cloned() { + if existing.is_object() { + let mut merged = existing; + deep_merge_json(&mut merged, value); + storage.record_value(key, merged); + continue; + } + } + } + storage.record_value(key, value); + } + }); +} + +/// Recursively merge `source` JSON object into `target`. +/// Keys in `source` overwrite matching keys in `target`. +/// Nested objects are merged recursively. +#[cfg(feature = "log-transformations")] +fn deep_merge_json(target: &mut serde_json::Value, source: serde_json::Value) { + if let (serde_json::Value::Object(target_map), serde_json::Value::Object(source_map)) = + (target, source) + { + for (key, value) in source_map { + let entry = target_map.entry(key).or_insert(serde_json::Value::Null); + if entry.is_object() && value.is_object() { + deep_merge_json(entry, value); + } else { + *entry = value; + } + } + } +} + +/// Like `set_nested_value` but takes pre-split path segments instead of a dotted string. +/// Avoids runtime `split('.')` — segments are pre-compiled at startup. +#[cfg(feature = "log-transformations")] +fn set_nested_value_from_segments( + target: &mut serde_json::Value, + segments: &[String], + value: serde_json::Value, +) { + if segments.is_empty() { + return; + } + if let (1, Some(seg)) = (segments.len(), segments.first()) { + target[seg.as_str()] = value; + return; + } + // Walk intermediate segments, creating objects as needed + let mut current = target; + for (i, segment) in segments.iter().enumerate() { + if i == segments.len() - 1 { + current[segment.as_str()] = value; + return; + } + if !current[segment.as_str()].is_object() { + current[segment.as_str()] = serde_json::json!({}); + } + current = &mut current[segment.as_str()]; + } +} + /// Configuration for events system #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, config_patch_derive::Patch)] pub struct EventConfig { @@ -484,6 +730,9 @@ pub struct EventConfig { /// Inbound request events. pub api_events: KafkaTopicConfig, #[serde(default)] + #[patch(ignore)] + pub transformation_mode: TransformationMode, + #[serde(default)] pub transformations: HashMap, // target_path → source_field #[serde(default)] pub static_values: HashMap, // target_path → static_value @@ -508,6 +757,7 @@ impl Default for EventConfig { brokers: vec!["localhost:9092".to_string()], connector_events: KafkaTopicConfig::default(), api_events: KafkaTopicConfig::default(), + transformation_mode: TransformationMode::default(), transformations: HashMap::new(), static_values: HashMap::new(), extractions: HashMap::new(), @@ -555,9 +805,11 @@ pub(crate) fn process_event_with_config( let normalize_path = |path: &str| -> String { path.replace("_DOT_", ".").replace("_dot_", ".") }; - // Process transformations + // Process transformations — collect source fields used for potential removal in replace mode + let mut used_source_fields: Vec<&str> = Vec::new(); for (target_path, source_field) in &config.transformations { if let Some(value) = result.get(source_field).cloned() { + used_source_fields.push(source_field.as_str()); let normalized_path = normalize_path(target_path); if let Err(e) = set_nested_value(&mut result, &normalized_path, value) { tracing::warn!( @@ -571,6 +823,16 @@ pub(crate) fn process_event_with_config( } } + // In replace mode, remove original source fields after all transformations complete. + // This is done after the loop so fan-out works (multiple targets reading the same source). + if matches!(config.transformation_mode, TransformationMode::Replace) { + if let Some(obj) = result.as_object_mut() { + for source_field in &used_source_fields { + obj.remove(*source_field); + } + } + } + // Process static values - log warnings but continue processing for (target_path, static_value) in &config.static_values { let normalized_path = normalize_path(target_path); diff --git a/crates/common/external-services/Cargo.toml b/crates/common/external-services/Cargo.toml index a0f20b626b..51b5b9774f 100644 --- a/crates/common/external-services/Cargo.toml +++ b/crates/common/external-services/Cargo.toml @@ -59,6 +59,10 @@ injector = { git = "https://github.com/juspay/hyperswitch", tag = "2026.06.18.0" connector_request_kafka = { path = "../connector_request_kafka", optional = true } url = "2.5.0" chrono = "0.4.31" +log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "log_utils", features = [ + "tracing", + "tracing-storage-api", +] } # OpenTelemetry (OTLP metrics push) — optional, enabled via the `otel` feature. opentelemetry = { version = "0.27", optional = true, default-features = false, features = [ @@ -76,6 +80,7 @@ injector-client = ["dep:injector"] connector-request-kafka = ["dep:connector_request_kafka"] # Push gRPC metrics over OTLP (in addition to the Prometheus /metrics endpoint). otel = ["dep:opentelemetry"] +log-transformations = ["common_utils/log-transformations"] [lints] workspace = true diff --git a/crates/common/external-services/src/service.rs b/crates/common/external-services/src/service.rs index 7c41ed561c..b26c30d60d 100644 --- a/crates/common/external-services/src/service.rs +++ b/crates/common/external-services/src/service.rs @@ -2,6 +2,8 @@ use std::{collections::HashMap, str::FromStr, sync::RwLock, time::Duration}; use base64::Engine; use common_enums::ApiClientError; +#[cfg(all(feature = "injector-client", feature = "log-transformations"))] +use common_utils::events::apply_log_fields; #[cfg(feature = "injector-client")] use common_utils::{ consts::{X_API_TAG, X_API_URL, X_SESSION_ID}, @@ -9,6 +11,7 @@ use common_utils::{ request::TransportType, }; use common_utils::{ + events::CompiledLogFields, ext_traits::AsyncExt, lineage, request::{Method, Request, RequestContent}, @@ -551,6 +554,10 @@ pub struct EventProcessingParams<'a> { pub merchant_id: &'a str, pub return_raw_connector_data: bool, pub connector_latency: ConnectorLatencyTracker, + /// Runtime kill-switch for log field application. + pub log_fields_enabled: bool, + /// Pre-compiled log fields (transformations + static values) for golden log lines. + pub log_fields: &'a CompiledLogFields, } #[cfg(feature = "injector-client")] @@ -1074,6 +1081,11 @@ where let elapsed = start.elapsed().as_millis(); tracing::Span::current().record("latency", elapsed); + // Apply outgoing log fields (transformations + static values) before emitting the golden log line + #[cfg(feature = "log-transformations")] + if event_params.log_fields_enabled { + apply_log_fields(event_params.log_fields); + } tracing::info!(tag = ?Tag::OutgoingApi, log_type = "api", "Outgoing Request completed"); result_with_integrity_check } diff --git a/crates/common/tracing-kafka/Cargo.toml b/crates/common/tracing-kafka/Cargo.toml index 89a9fc7318..45f51a1f18 100644 --- a/crates/common/tracing-kafka/Cargo.toml +++ b/crates/common/tracing-kafka/Cargo.toml @@ -11,7 +11,7 @@ rdkafka = "0.36" serde_json = { workspace = true } tokio = "1.0" thiserror = { workspace = true } -log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "log_utils", features = ["tracing"] } +log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "log_utils", features = ["tracing"] } # Optional dependencies for metrics prometheus = { version = "0.13", optional = true } diff --git a/crates/common/ucs_env/Cargo.toml b/crates/common/ucs_env/Cargo.toml index 56202101e9..700d778a39 100644 --- a/crates/common/ucs_env/Cargo.toml +++ b/crates/common/ucs_env/Cargo.toml @@ -49,16 +49,16 @@ tokio = { version = "1.48.0", features = [ tonic = { workspace = true } tonic-reflection = "0.14.0" http = "1.2.0" -log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "log_utils", features = [ +log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "log_utils", features = [ "tracing", ] } -build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "build_info", features = [ +build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "build_info", features = [ "cargo-workspace", "framework-libs-members-env", ] } [build-dependencies] -build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "build_info", features = [ +build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "build_info", features = [ "cargo-workspace-build", "vergen-gix-build", "framework-libs-members-env", @@ -68,6 +68,7 @@ build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "24356 default = [] kafka = ["tracing-kafka"] otel = ["dep:opentelemetry", "dep:opentelemetry-otlp", "dep:opentelemetry_sdk"] +log-transformations = ["common_utils/log-transformations"] [lints] workspace = true \ No newline at end of file diff --git a/crates/common/ucs_env/src/configs.rs b/crates/common/ucs_env/src/configs.rs index 7d9afce9ab..0ec48e28fd 100644 --- a/crates/common/ucs_env/src/configs.rs +++ b/crates/common/ucs_env/src/configs.rs @@ -6,7 +6,10 @@ use std::sync::Arc; use common_utils::{ connector_request_kafka::{ConnectorRequestKafkaConfig, ConnectorRequestKafkaConfigPatch}, consts, - events::{EventConfig, EventConfigPatch, RuntimeMetadata, RuntimeMetadataPatch}, + events::{ + CompiledLogFieldsConfig, EventConfig, EventConfigPatch, RuntimeMetadata, + RuntimeMetadataPatch, + }, metadata::{HeaderMaskingConfig, HeaderMaskingConfigPatch}, SuperpositionConfig, }; @@ -53,6 +56,12 @@ pub struct Config { #[serde(skip)] #[patch(ignore)] pub superposition_config: Option>, + /// Pre-compiled log fields for golden log lines. + /// Compiled at startup from `[log.fields.incoming]` and `[log.fields.outgoing]`. + /// Recompiled per-request when `x-config-override` patches `log.fields`. + #[serde(skip)] + #[patch(ignore)] + pub log_fields: Arc, } #[derive(Clone, Deserialize, Debug, Default, Serialize, PartialEq, config_patch_derive::Patch)] @@ -328,6 +337,22 @@ impl WebhookSourceVerificationCall { } impl Config { + /// Recompute derived / cached fields from the raw config values. + /// + /// Call this after deserialization **and** after applying a config-override patch. + /// Any `#[serde(skip)] #[patch(ignore)]` field that is derived from patchable + /// config should be rebuilt here. + pub fn post_patch_processing(&mut self) { + #[cfg(feature = "log-transformations")] + { + self.log_fields = Arc::new(CompiledLogFieldsConfig::compile( + self.log.fields.enabled, + &self.log.fields.incoming, + &self.log.fields.outgoing, + )); + } + } + /// Function to build the configuration by picking it from default locations pub fn new() -> Result { Self::new_with_config_path(None) @@ -363,6 +388,12 @@ impl Config { error.into_inner() })?; + let config = { + let mut config = config; + config.post_patch_processing(); + config + }; + // Validate the environment field config.common.validate()?; diff --git a/crates/common/ucs_env/src/logger/config.rs b/crates/common/ucs_env/src/logger/config.rs index 6ec5d92e58..c9a7938b69 100644 --- a/crates/common/ucs_env/src/logger/config.rs +++ b/crates/common/ucs_env/src/logger/config.rs @@ -2,7 +2,57 @@ //! Logger-specific config. //! +use std::collections::HashMap; + +use common_utils::config_patch::Patch; +pub use common_utils::events::LogFieldEntry; use serde::{Deserialize, Serialize}; + +/// Unified log fields for golden log lines, split by direction. +/// +/// Each map key is a target path (dotted paths like `"api_details.url"` create nested JSON). +/// Each value is a [`LogFieldEntry`] — either a literal or a source field reference. +/// +/// Patchable via `x-config-override` header with **merge** semantics: +/// override entries are added to / replace matching base entries; unmentioned entries stay. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] +pub struct LogFields { + /// Runtime toggle: when `false`, compiled log fields are not applied + /// even though the `log-transformations` feature is compiled in. + /// Defaults to `false` — must be explicitly enabled in config. + #[serde(default)] + pub enabled: bool, + #[serde(default)] + pub incoming: HashMap, + #[serde(default)] + pub outgoing: HashMap, +} + +/// Patch type for [`LogFields`] — manually defined for merge semantics. +/// +/// When applied, each direction's map is **extended** (not replaced): +/// new keys are added, existing keys are overwritten, absent keys are kept. +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct LogFieldsPatch { + pub enabled: Option, + pub incoming: Option>, + pub outgoing: Option>, +} + +impl Patch for LogFields { + fn apply(&mut self, patch: LogFieldsPatch) { + if let Some(enabled) = patch.enabled { + self.enabled = enabled; + } + if let Some(incoming) = patch.incoming { + self.incoming.extend(incoming); + } + if let Some(outgoing) = patch.outgoing { + self.outgoing.extend(outgoing); + } + } +} + /// Log config settings. #[derive(Debug, Deserialize, Clone, Serialize, PartialEq, config_patch_derive::Patch)] pub struct Log { @@ -11,6 +61,13 @@ pub struct Log { /// Logging to Kafka (optional). #[serde(default)] pub kafka: Option, + /// Unified log fields for golden log lines. + /// Each entry is either a literal value or a source field reference. + /// Dotted target paths create nested JSON objects. + /// Patchable per-request via `x-config-override` with merge semantics. + #[serde(default)] + #[patch(patch_type = LogFieldsPatch)] + pub fields: LogFields, } /// Logging to a console. diff --git a/crates/grpc-server/grpc-server/Cargo.toml b/crates/grpc-server/grpc-server/Cargo.toml index 938418cb2d..bf1975e16b 100644 --- a/crates/grpc-server/grpc-server/Cargo.toml +++ b/crates/grpc-server/grpc-server/Cargo.toml @@ -66,10 +66,11 @@ prost-types = "0.14" rustc-hash = "2.0" gethostname = "0.5.0" once_cell = "1.19.0" -log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "log_utils", features = [ +log_utils = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "log_utils", features = [ "tracing", + "tracing-storage-api", ] } -build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "build_info", features = [ +build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "build_info", features = [ "cargo-workspace", "framework-libs-members-env", ] } @@ -77,7 +78,7 @@ uuid = { workspace = true } chrono = "0.4.31" [build-dependencies] -build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "243562041252fe5897ce888d20b715ffdc3767ce", package = "build_info", features = [ +build_info = { git = "https://github.com/juspay/framework-libs-rs", rev = "76613f5d0c72fd3d26a3403ae859c2a7545e8dd2", package = "build_info", features = [ "cargo-workspace-build", "vergen-gix-build", "framework-libs-members-env", @@ -101,6 +102,7 @@ connector-request-kafka = ["dep:connector_request_kafka", "external-services/con # Push gRPC metrics over OTLP to an OpenTelemetry Collector, in addition to the # Prometheus /metrics scrape endpoint. otel = ["ucs_env/otel", "external-services/otel"] +log-transformations = ["common_utils/log-transformations", "external-services/log-transformations", "ucs_env/log-transformations"] [lints] workspace = true diff --git a/crates/grpc-server/grpc-server/src/server/disputes.rs b/crates/grpc-server/grpc-server/src/server/disputes.rs index 5c2eb10b94..9ed6c146ff 100644 --- a/crates/grpc-server/grpc-server/src/server/disputes.rs +++ b/crates/grpc-server/grpc-server/src/server/disputes.rs @@ -185,6 +185,8 @@ impl DisputeService for Disputes { merchant_id: merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency, + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( @@ -425,6 +427,8 @@ impl DisputeService for Disputes { merchant_id: merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency, + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( diff --git a/crates/grpc-server/grpc-server/src/server/events.rs b/crates/grpc-server/grpc-server/src/server/events.rs index 8299b1aa34..e5bbd55eb0 100644 --- a/crates/grpc-server/grpc-server/src/server/events.rs +++ b/crates/grpc-server/grpc-server/src/server/events.rs @@ -505,6 +505,8 @@ impl EventServiceImpl { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response_result = Box::pin( @@ -614,6 +616,8 @@ impl EventServiceImpl { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response_result = Box::pin( @@ -723,6 +727,8 @@ impl EventServiceImpl { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response_result = Box::pin( @@ -829,6 +835,8 @@ impl EventServiceImpl { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response_result = Box::pin( @@ -935,6 +943,8 @@ impl EventServiceImpl { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response_result = Box::pin( @@ -1030,6 +1040,8 @@ async fn verify_webhook_source_external( merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; match Box::pin( diff --git a/crates/grpc-server/grpc-server/src/server/payments.rs b/crates/grpc-server/grpc-server/src/server/payments.rs index 1ccdd45768..ee56babf66 100644 --- a/crates/grpc-server/grpc-server/src/server/payments.rs +++ b/crates/grpc-server/grpc-server/src/server/payments.rs @@ -561,6 +561,7 @@ impl Payments { })?; // Execute connector processing + let event_params = EventProcessingParams { connector_name: &connector.get_connector_name(), service_name, @@ -578,6 +579,8 @@ impl Payments { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; // Execute connector processing - ONLY the authorize call @@ -716,6 +719,8 @@ impl Payments { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( @@ -1113,6 +1118,7 @@ impl PaymentService for Payments { })) })?; + let event_params = EventProcessingParams { connector_name: &connector.get_connector_name(), service_name: &service_name, @@ -1130,6 +1136,8 @@ impl PaymentService for Payments { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; // handle_response field removed from proto (field 5 reserved) @@ -2591,6 +2599,7 @@ impl PaymentMethod { })?; // Execute connector processing + let event_params = EventProcessingParams { connector_name: &connector.get_connector_name(), service_name, @@ -2608,6 +2617,8 @@ impl PaymentMethod { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( @@ -2745,6 +2756,8 @@ impl PaymentMethod { return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), runtime_metadata: &config.runtime_metadata, + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( @@ -2844,6 +2857,7 @@ impl MerchantAuthentication { })?; // Create event processing parameters + let external_event_params = EventProcessingParams { connector_name, service_name, @@ -2861,6 +2875,8 @@ impl MerchantAuthentication { merchant_id: event_params.merchant_id, return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: event_params.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; // Execute connector processing @@ -2985,6 +3001,7 @@ impl MerchantAuthentication { })?; // Execute connector processing + let external_event_params = EventProcessingParams { connector_name, service_name, @@ -3002,6 +3019,8 @@ impl MerchantAuthentication { merchant_id: event_params.merchant_id, return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: event_params.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( @@ -3564,6 +3583,7 @@ impl RecurringPaymentService for RecurringPayments { })) })?; + let event_params = EventProcessingParams { connector_name: &metadata_payload.connector.get_connector_name(), service_name: &service_name, @@ -3581,6 +3601,8 @@ impl RecurringPaymentService for RecurringPayments { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let response = Box::pin( diff --git a/crates/grpc-server/grpc-server/src/utils.rs b/crates/grpc-server/grpc-server/src/utils.rs index 72b103f699..8bc099a432 100644 --- a/crates/grpc-server/grpc-server/src/utils.rs +++ b/crates/grpc-server/grpc-server/src/utils.rs @@ -4,10 +4,12 @@ pub use ucs_interface_common::config::*; pub use ucs_interface_common::flow::*; pub use ucs_interface_common::metadata::*; +#[cfg(feature = "log-transformations")] +use common_utils::events::apply_log_fields; use common_utils::{ consts::{self, Env}, errors::CustomResult, - events::{Event, EventStage, FlowName, MaskedSerdeValue}, + events::{CompiledLogFields, Event, EventStage, FlowName, MaskedSerdeValue}, lineage::LineageIds, superposition_config::{get_connector_urls, ConnectorUrls, SuperpositionConfig}, types::ExecutionMode, @@ -289,8 +291,11 @@ where Ok(()) } -pub fn log_after_initialization(result: &Result, tonic::Status>) -where +pub fn log_after_initialization( + result: &Result, tonic::Status>, + log_fields_enabled: bool, + log_fields: &CompiledLogFields, +) where T: serde::Serialize + std::fmt::Debug, { let current_span = tracing::Span::current(); @@ -326,6 +331,16 @@ where current_span.record("status_code", status.code().to_string()); } } + // Apply unified log fields (transformations + static values) before emitting the golden log line + #[cfg(feature = "log-transformations")] + if log_fields_enabled { + apply_log_fields(log_fields); + } + #[cfg(not(feature = "log-transformations"))] + { + let _ = log_fields; + let _ = log_fields_enabled; + } tracing::info!("Golden Log Line (incoming - response)"); } @@ -376,7 +391,11 @@ where .await; let grpc_response = handler_result.into_grpc_status(); - log_after_initialization(&grpc_response); + log_after_initialization( + &grpc_response, + config.log_fields.enabled, + &config.log_fields.incoming, + ); #[cfg(feature = "otel")] observe_internal_latency( @@ -440,7 +459,11 @@ where .await; let grpc_response = handler_result.into_grpc_status(); - log_after_initialization(&grpc_response); + log_after_initialization( + &grpc_response, + config.log_fields.enabled, + &config.log_fields.incoming, + ); #[cfg(feature = "otel")] observe_internal_latency( @@ -710,6 +733,8 @@ macro_rules! implement_connector_operation { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; // The connector round-trip is identical for both holders → written once, @@ -1071,6 +1096,8 @@ macro_rules! implement_connector_operation { merchant_id: metadata_payload.merchant_id.as_str(), return_raw_connector_data: config.common.return_raw_connector_data, connector_latency: metadata_payload.connector_latency.clone(), + log_fields_enabled: config.log_fields.enabled, + log_fields: &config.log_fields.outgoing, }; let call_connector_action = connector_integration.get_call_connector_action(); let response_result = external_services::service::execute_connector_processing_step( diff --git a/crates/types-traits/ucs_interface_common/src/config.rs b/crates/types-traits/ucs_interface_common/src/config.rs index a7f0b01e8f..fbf9375bab 100644 --- a/crates/types-traits/ucs_interface_common/src/config.rs +++ b/crates/types-traits/ucs_interface_common/src/config.rs @@ -33,6 +33,7 @@ pub fn merge_config_with_override( let mut merged_config = config; merged_config.apply(override_patch); + merged_config.post_patch_processing(); tracing::info!("Config override applied successfully");