Skip to content

Commit 97f244a

Browse files
authored
feat: add RUM SDK Injection (#93)
1 parent a01af12 commit 97f244a

31 files changed

+2273
-51
lines changed

.circleci/continue_config.yml

+32-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ jobs:
1919
ARCH: x86_64
2020
MAKE_JOB_COUNT: 8
2121
NGINX_VERSION: << parameters.nginx-version >>
22+
RUM: << parameters.rum >>
2223
WAF: << parameters.waf >>
2324
machine:
2425
image: ubuntu-2204:current
2526
parameters:
2627
nginx-version:
2728
type: string
29+
rum:
30+
default: "OFF"
31+
enum:
32+
- "ON"
33+
- "OFF"
34+
type: enum
2835
waf:
2936
enum:
3037
- "ON"
@@ -63,12 +70,19 @@ jobs:
6370
ARCH: aarch64
6471
MAKE_JOB_COUNT: 8
6572
NGINX_VERSION: << parameters.nginx-version >>
73+
RUM: << parameters.rum >>
6674
WAF: << parameters.waf >>
6775
machine:
6876
image: ubuntu-2204:current
6977
parameters:
7078
nginx-version:
7179
type: string
80+
rum:
81+
default: "OFF"
82+
enum:
83+
- "ON"
84+
- "OFF"
85+
type: enum
7286
waf:
7387
enum:
7488
- "ON"
@@ -139,6 +153,9 @@ jobs:
139153
steps:
140154
- checkout
141155
- run: git submodule sync && git submodule update --init --recursive
156+
- run:
157+
command: pip install -r requirements.txt
158+
name: Install Python dependencies
142159
- run: echo -e "ARCH=amd64\nBASE_IMAGE=nginx:1.26.0\n" > nginx-version-info
143160
- run:
144161
command: make coverage
@@ -160,7 +177,7 @@ jobs:
160177
- checkout
161178
- run:
162179
command: |
163-
pip install yapf
180+
pip install -r requirements.txt
164181
update-alternatives --install /usr/local/bin/yapf3 yapf3 /usr/local/bin/yapf 100
165182
name: Install Python dependencies
166183
- run: make lint
@@ -232,6 +249,7 @@ jobs:
232249
test:
233250
environment:
234251
DOCKER_BUILDKIT: 1
252+
RUM: << parameters.rum >>
235253
WAF: << parameters.waf >>
236254
executor:
237255
image: cimg/python:3.10.13
@@ -244,10 +262,22 @@ jobs:
244262
type: string
245263
nginx-version:
246264
type: string
265+
rum:
266+
default: "OFF"
267+
enum:
268+
- "ON"
269+
- "OFF"
270+
type: enum
247271
waf:
248-
type: string
272+
enum:
273+
- "ON"
274+
- "OFF"
275+
type: enum
249276
steps:
250277
- checkout
278+
- run:
279+
command: pip install -r requirements.txt
280+
name: Install Python dependencies
251281
- attach_workspace:
252282
at: /tmp/workspace
253283
- run: mv -v /tmp/workspace/.musl-build/ngx_http_datadog_module.so* test/services/nginx/

.circleci/src/@jobs.yml

+32-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ jobs:
88
enum:
99
- 'ON'
1010
- 'OFF'
11+
rum:
12+
type: enum
13+
enum:
14+
- 'ON'
15+
- 'OFF'
16+
default: 'OFF'
1117
steps:
1218
- checkout
1319
- run: git submodule sync && git submodule update --init --recursive
@@ -42,6 +48,7 @@ jobs:
4248
ARCH: x86_64
4349
MAKE_JOB_COUNT: 8
4450
WAF: "<< parameters.waf >>"
51+
RUM: "<< parameters.rum >>"
4552
NGINX_VERSION: "<< parameters.nginx-version >>"
4653
build_arm64:
4754
parameters:
@@ -52,6 +59,12 @@ jobs:
5259
enum:
5360
- 'ON'
5461
- 'OFF'
62+
rum:
63+
type: enum
64+
enum:
65+
- 'ON'
66+
- 'OFF'
67+
default: 'OFF'
5568
steps:
5669
- checkout
5770
- run: git submodule sync && git submodule update --init --recursive
@@ -81,13 +94,17 @@ jobs:
8194
ARCH: aarch64
8295
MAKE_JOB_COUNT: 8
8396
WAF: "<< parameters.waf >>"
97+
RUM: "<< parameters.rum >>"
8498
NGINX_VERSION: "<< parameters.nginx-version >>"
8599
coverage:
86100
environment:
87101
DOCKER_BUILDKIT: 1
88102
steps:
89103
- checkout
90104
- run: git submodule sync && git submodule update --init --recursive
105+
- run:
106+
name: Install Python dependencies
107+
command: pip install -r requirements.txt
91108
- run: echo -e "ARCH=amd64\nBASE_IMAGE=nginx:1.26.0\n" > nginx-version-info
92109
- run:
93110
command: 'make coverage'
@@ -114,16 +131,29 @@ jobs:
114131
arch:
115132
type: string
116133
waf:
117-
type: string
134+
type: enum
135+
enum:
136+
- 'ON'
137+
- 'OFF'
138+
rum:
139+
type: enum
140+
enum:
141+
- 'ON'
142+
- 'OFF'
143+
default: 'OFF'
118144
executor:
119145
name: docker-<< parameters.arch >>
120146
image: cimg/python:3.10.13
121147
environment:
122148
# https://github.com/containers/podman/issues/13889
123149
DOCKER_BUILDKIT: 1
124150
WAF: "<< parameters.waf >>"
151+
RUM: "<< parameters.rum >>"
125152
steps:
126153
- checkout
154+
- run:
155+
name: Install Python dependencies
156+
command: pip install -r requirements.txt
127157
- attach_workspace:
128158
at: "/tmp/workspace"
129159
- run: mv -v /tmp/workspace/.musl-build/ngx_http_datadog_module.so* test/services/nginx/
@@ -171,7 +201,7 @@ jobs:
171201
- run:
172202
name: Install Python dependencies
173203
command: |
174-
pip install yapf
204+
pip install -r requirements.txt
175205
update-alternatives --install /usr/local/bin/yapf3 yapf3 /usr/local/bin/yapf 100
176206
- run: make lint
177207
shellcheck:

CMakeLists.txt

+43-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(NGINX_DATADOG_VERSION 1.3.0)
1111
project(ngx_http_datadog_module VERSION ${NGINX_DATADOG_VERSION})
1212

1313
option(NGINX_DATADOG_ASM_ENABLED "Build with libddwaf" ON)
14+
option(NGINX_DATADOG_RUM_ENABLED "Build with RUM injection" OFF)
1415
set(NGINX_SRC_DIR "" CACHE PATH "The path to a directory with nginx sources")
1516
set(NGINX_VERSION "" CACHE STRING "The nginx version")
1617
if (NGINX_SRC_DIR STREQUAL "" AND NGINX_VERSION STREQUAL "")
@@ -19,18 +20,31 @@ endif()
1920
option(NGINX_PATCH_AWAY_LIBC "Patch away libc dependency" OFF)
2021
option(NGINX_COVERAGE "Add coverage instrumentation" OFF)
2122

22-
message(STATUS "nginx-datadog version=[${NGINX_DATADOG_VERSION}]")
23-
if (NGINX_DATADOG_ASM_ENABLED)
24-
message(STATUS "nginx-datadog products: tracing appsec")
25-
else ()
26-
message(STATUS "nginx-datadog products: tracing")
23+
if (NGINX_DATADOG_RUM_ENABLED AND NGINX_DATADOG_ASM_ENABLED)
24+
message(FATAL_ERROR "ASM and RUM features are mutually exclusive")
2725
endif ()
2826

2927
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
3028
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0")
3129
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -O0")
3230
endif()
3331

32+
message(STATUS "nginx-datadog version=[${NGINX_DATADOG_VERSION}]")
33+
34+
set(NGINX_DATADOG_PRODUCTS_LIST "tracing")
35+
if (NGINX_DATADOG_ASM_ENABLED)
36+
list(APPEND NGINX_DATADOG_PRODUCTS_LIST "appsec")
37+
endif ()
38+
39+
if (NGINX_DATADOG_RUM_ENABLED)
40+
list(APPEND NGINX_DATADOG_PRODUCTS_LIST "rum-injection")
41+
endif ()
42+
43+
list(JOIN NGINX_DATADOG_PRODUCTS_LIST " " NGINX_DATADOG_PRODUCTS)
44+
unset(NGINX_DATADOG_PRODUCTS_LIST)
45+
46+
message(STATUS "nginx-datadog products: ${NGINX_DATADOG_PRODUCTS}")
47+
3448
# Make curl link against a static zlib (requires cmake 3.24)
3549
set(ZLIB_USE_STATIC_LIBS ON)
3650

@@ -78,6 +92,19 @@ if(NGINX_DATADOG_ASM_ENABLED)
7892
unset(ASM_RULES)
7993
endif()
8094

95+
if(NGINX_DATADOG_RUM_ENABLED)
96+
execute_process (
97+
COMMAND cargo pkgid --package inject-browser-sdk --manifest-path "${CMAKE_CURRENT_SOURCE_DIR}/deps/inject-browser-sdk/Cargo.toml"
98+
OUTPUT_VARIABLE RUM_SDK_INJECTOR_PKGID
99+
)
100+
string(REGEX REPLACE ".*@(.*)" "\\1" RUM_SDK_INJECTOR_VERSION ${RUM_SDK_INJECTOR_PKGID})
101+
string(STRIP "${RUM_SDK_INJECTOR_VERSION}" RUM_SDK_INJECTOR_VERSION)
102+
103+
unset(RUM_SDK_INJECTOR_PKGID)
104+
105+
add_subdirectory(deps)
106+
endif()
107+
81108
include(./cmake/generate_build_id.cmake)
82109

83110
# Generate the build identifier.
@@ -125,6 +152,17 @@ if(NGINX_DATADOG_ASM_ENABLED)
125152
src/security/waf_remote_cfg.cpp)
126153
target_compile_definitions(ngx_http_datadog_module PRIVATE WITH_WAF)
127154
endif()
155+
if(NGINX_DATADOG_RUM_ENABLED)
156+
target_sources(ngx_http_datadog_module
157+
PRIVATE
158+
src/rum/config.cpp
159+
src/rum/injection.cpp
160+
)
161+
target_compile_definitions(ngx_http_datadog_module PRIVATE WITH_RUM)
162+
163+
target_link_libraries(ngx_http_datadog_module inject_browser_sdk)
164+
165+
endif()
128166

129167
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
130168
target_compile_options(ngx_http_datadog_module PRIVATE -Wall -Werror)

Makefile

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
BUILD_DIR ?= .build
44
BUILD_TYPE ?= RelWithDebInfo
55
WAF ?= OFF
6+
RUM ?= OFF
67
MAKE_JOB_COUNT ?= $(shell nproc)
78
PWD ?= $(shell pwd)
89
NGINX_SRC_DIR ?= $(PWD)/nginx
@@ -17,7 +18,7 @@ SHELL := /bin/bash
1718
build: build-deps sources
1819
# -DCMAKE_C_FLAGS=-I/opt/homebrew/Cellar/pcre2/10.42/include/ -DCMAKE_CXX_FLAGS=-I/opt/homebrew/Cellar/pcre2/10.42/include/ -DCMAKE_LDFLAGS=-L/opt/homebrew/Cellar/pcre2/10.42/lib -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang
1920
cmake -B$(BUILD_DIR) -DNGINX_SRC_DIR=$(NGINX_SRC_DIR) \
20-
-DNGINX_COVERAGE=$(COVERAGE) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DNGINX_DATADOG_ASM_ENABLED=$(WAF) . \
21+
-DNGINX_COVERAGE=$(COVERAGE) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DNGINX_DATADOG_ASM_ENABLED=$(WAF) -DNGINX_DATADOG_RUM_ENABLED=$(RUM) . \
2122
&& cmake --build $(BUILD_DIR) -j $(MAKE_JOB_COUNT) -v
2223
chmod 755 $(BUILD_DIR)/ngx_http_datadog_module.so
2324
@echo 'build successful 👍'
@@ -98,6 +99,7 @@ build-musl:
9899
--env BUILD_TYPE=$(BUILD_TYPE) \
99100
--env NGINX_VERSION=$(NGINX_VERSION) \
100101
--env WAF=$(WAF) \
102+
--env RUM=$(RUM) \
101103
--env COVERAGE=$(COVERAGE) \
102104
--mount "type=bind,source=$(PWD),destination=/mnt/repo" \
103105
$(DOCKER_REPOS):latest \
@@ -112,6 +114,7 @@ build-musl-aux:
112114
-DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \
113115
-DNGINX_VERSION="$(NGINX_VERSION)" \
114116
-DNGINX_DATADOG_ASM_ENABLED="$(WAF)" . \
117+
-DNGINX_DATADOG_RUM_ENABLED="$(RUM)" . \
115118
-DNGINX_COVERAGE=$(COVERAGE) \
116119
&& cmake --build .musl-build -j $(MAKE_JOB_COUNT) -v
117120

build_env/Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,8 @@ RUN clang --sysroot /sysroot/${ARCH}-none-linux-musl/ -fpie -O2 -fno-omit-frame-
6969

7070
# Install dependencies for nginx
7171
RUN apk add --no-cache pcre-dev pcre2-dev zlib-dev openssl-dev perl
72+
73+
# Install Rust toolchain
74+
RUN apk add curl
75+
RUN curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -yq \
76+
&& ln -s ~/.cargo/bin/cargo /usr/bin/cargo

deps/CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
include(corrosion.cmake)
2+
3+
corrosion_import_crate(MANIFEST_PATH inject-browser-sdk/lib/Cargo.toml)
4+
5+
corrosion_experimental_cbindgen(
6+
TARGET inject_browser_sdk
7+
HEADER_NAME injectbrowsersdk.h
8+
FLAGS --config ${CMAKE_SOURCE_DIR}/deps/cbindgen.toml
9+
)
10+

deps/cbindgen.toml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
language = "C++"
2+
3+
pragma_once = true
4+
include_version = false

deps/corrosion.cmake

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
include(FetchContent)
2+
3+
FetchContent_Declare(
4+
Corrosion
5+
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
6+
GIT_TAG v0.5 # Optionally specify a commit hash, version tag or branch here
7+
)
8+
# Set any global configuration variables such as `Rust_TOOLCHAIN` before this line!
9+
FetchContent_MakeAvailable(Corrosion)

requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
werkzeug==3.0.3
2+
yapf==0.40.2

src/datadog_conf.h

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ extern "C" {
1212

1313
#include <datadog/propagation_style.h>
1414
#include <datadog/trace_sampler_config.h>
15+
#ifdef WITH_RUM
16+
#include <injectbrowsersdk.h>
17+
#endif
1518

1619
#include <string>
1720
#include <vector>
@@ -222,6 +225,11 @@ struct datadog_loc_conf_t {
222225
#ifdef WITH_WAF
223226
ngx_thread_pool_t *waf_pool{nullptr};
224227
#endif
228+
229+
#ifdef WITH_RUM
230+
ngx_flag_t rum_enable;
231+
Snippet *rum_snippet;
232+
#endif
225233
};
226234

227235
} // namespace nginx

0 commit comments

Comments
 (0)