From 6aa6467d261c55aa26cf12cfb37f9e08a09221b5 Mon Sep 17 00:00:00 2001 From: Jeff Cheng <83052155+jeffreyc-splunk@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:38:35 -0500 Subject: [PATCH] Update installation prefix for splunk-otel-js (#4038) * Update installation prefix for splunk-otel-js * don't use --prefix * Update changelog --- .github/workflows/auto-instrumentation.yml | 9 ++- CHANGELOG.md | 7 ++ docs/getting-started/linux-installer.md | 41 ++++++++---- docs/getting-started/linux-manual.md | 13 ++-- instrumentation/README.md | 4 +- .../fpm/etc/splunk/zeroconfig/node.conf | 2 +- .../00-splunk-otel-auto-instrumentation.conf | 2 +- .../packaging/installer/install.sh | 64 ++++++++++--------- .../packaging/tests/installer_test.py | 12 ++-- .../instrumentation/instrumentation_test.py | 5 +- .../instrumentation/libsplunk-node-test.conf | 2 +- 11 files changed, 100 insertions(+), 61 deletions(-) diff --git a/.github/workflows/auto-instrumentation.yml b/.github/workflows/auto-instrumentation.yml index 2d2ea28716..732639dc19 100644 --- a/.github/workflows/auto-instrumentation.yml +++ b/.github/workflows/auto-instrumentation.yml @@ -98,7 +98,8 @@ jobs: fi distro=$(for d in $dockerfiles; do echo -n "\"$d\","; done) arch="\"amd64\", \"arm64\"" - matrix="{\"DISTRO\": [${distro%,}], \"ARCH\": [${arch}]}" + testcase="\"express\",\"tomcat\"" + matrix="{\"DISTRO\": [${distro%,}], \"ARCH\": [${arch}], \"TESTCASE\": [${testcase}]}" echo "$matrix" | jq echo "matrix=${matrix}" >> $GITHUB_OUTPUT outputs: @@ -169,7 +170,8 @@ jobs: # workaround for pytest substring matching distro="amazonlinux-2 and not amazonlinux-2023" fi - python3 -u -m pytest -s --verbose -k "$distro and ${{ matrix.ARCH }}" \ + testcase="${{ matrix.TESTCASE }} or uninstall" + python3 -u -m pytest -s --verbose -k "$distro and ${{ matrix.ARCH }} and ($testcase)" \ internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py # qemu, networking, running systemd in containers, etc., can be flaky @@ -181,6 +183,7 @@ jobs: # workaround for pytest substring matching distro="amazonlinux-2 and not amazonlinux-2023" fi - python3 -u -m pytest -s --verbose -k "$distro and ${{ matrix.ARCH }}" \ + testcase="${{ matrix.TESTCASE }} or uninstall" + python3 -u -m pytest -s --verbose -k "$distro and ${{ matrix.ARCH }} and ($testcase)" \ --last-failed \ internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py diff --git a/CHANGELOG.md b/CHANGELOG.md index af5e99b57b..c5f000cfcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Unreleased +### 🛑 Breaking changes 🛑 + +- (Splunk) Node.js Auto Instrumentation: + - The `NODE_OPTIONS` environment variable in the default config file has been updated to load the Node.js SDK from an absolute path (`/usr/lib/splunk-instrumentation/splunk-otel-js/node_modules/@splunk/otel/instrument`). + - The Linux installer script now installs the Node.js SDK to `/usr/lib/splunk-instrumentation/splunk-otel-js` instead of globally. + - The `--npm-command` Linux installer script option is no longer supported. To specify a custom path to `npm`, use the `--npm-path ` option. + ## v0.90.0 This Splunk OpenTelemetry Collector release includes changes from the [opentelemetry-collector v0.90.1](https://github.com/open-telemetry/opentelemetry-collector/releases/tag/v0.90.1) and the [opentelemetry-collector-contrib v0.90.0](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.90.0) releases where appropriate. diff --git a/docs/getting-started/linux-installer.md b/docs/getting-started/linux-installer.md index 298628967e..7a3303b871 100644 --- a/docs/getting-started/linux-installer.md +++ b/docs/getting-started/linux-installer.md @@ -360,26 +360,26 @@ Auto Instrumentation to take effect. If running the installer script ***with*** Node.js Auto Instrumentation, the following are required: - `npm` is required to install the Node.js Auto Instrumentation package. If - `npm` is not installed or not found in the user's default `PATH`, the - installer script will automatically skip installation and configuration of - the Node.js agent. Run the installer script with the - `--without-instrumentation-sdk node` option to explicitly skip Node.js. -- By default, the Node.js Auto Instrumentation package will be installed with - the `npm install --global` command. Run the installer script with the - `--npm-command ""` option to specify a custom command (wrapped in - quotes). For example: + `npm` is not installed or not found with the `command -v npm` shell command, + the installer script will automatically skip installation and configuration + of the Node.js agent. Use the `--npm-path ` option to specify a custom + path to `npm`. For example: ``` curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh && \ - sudo sh /tmp/splunk-otel-collector.sh --with-instrumentation --npm-command "/path/to/npm install --prefix /my/custom/path" --realm SPLUNK_REALM -- SPLUNK_ACCESS_TOKEN + sudo sh /tmp/splunk-otel-collector.sh --with-instrumentation --npm-path /path/to/npm --realm SPLUNK_REALM -- SPLUNK_ACCESS_TOKEN ``` -- Ensure that all Node.js applications/services to be instrumented have access - to the installation path of the Node.js Auto Instrumentation package. - For `arm64/aarch64` architectures, the following package groups will automatically be installed in order to build/compile the Node.js Auto Instrumentation package: - Debian/Ubuntu: `build-essential` - CentOS/Oracle/Red Hat/Amazon: `Development Tools` - Suse: `devel_basis` and `devel_C_C++` +- To explicitly skip Node.js Auto Instrumentation, run the installer script + with the `--without-instrumentation-sdk node` option. For example: + ``` + curl -sSL https://dl.signalfx.com/splunk-otel-collector.sh > /tmp/splunk-otel-collector.sh && \ + sudo sh /tmp/splunk-otel-collector.sh --with-instrumentation --without-instrumentation-sdk node --realm SPLUNK_REALM -- SPLUNK_ACCESS_TOKEN + ``` #### Post-Install Configuration @@ -442,6 +442,25 @@ system (requires `root` privileges): sudo zypper update splunk-otel-auto-instrumentation ``` +The latest `splunk-otel-auto-instrumentation` deb/rpm package may provide an +updated version of the Node.js Auto Instrumentation agent (check the +[GitHub Release notes]( +https://github.com/signalfx/splunk-otel-collector/releases)). To update the +Node.js agent to the latest provided version, run the following command +(requires `npm`): +``` +cd /usr/lib/splunk-instrumentation/splunk-otel-js && \ +sudo npm install /usr/lib/splunk-instrumentation/splunk-otel-js.tgz + +# WARNING: The default Auto Instrumentation configuration expects the Node.js +# agent to be installed the /usr/lib/splunk-instrumentation/splunk-otel-js +# directory, as specified the command above. If the installation is changed to +# a different path, manually update the path for the NODE_OPTIONS +# environment variable in either /etc/splunk/zeroconfig/node.conf or +# /usr/lib/systemd/system.conf.d/00-splunk-otel-auto-instrumentation.conf +# accordingly. +``` + **Important**: After the `splunk-otel-auto-instrumentation` is upgraded, the `/usr/lib/splunk-instrumentation/libsplunk.so` shared object library path will automatically be removed from `/etc/ld.so.preload`, if it exists. If diff --git a/docs/getting-started/linux-manual.md b/docs/getting-started/linux-manual.md index 2a26121e54..abfcc4d7d0 100644 --- a/docs/getting-started/linux-manual.md +++ b/docs/getting-started/linux-manual.md @@ -346,13 +346,18 @@ To manually activate and configure the Auto Instrumentation agents: - [Node.js](https://docs.splunk.com/Observability/en/gdi/get-data-in/application/nodejs/nodejs-otel-requirements.html) 2. If Auto Instrumentation for Node.js is required, install the provided `/usr/lib/splunk-instrumentation/splunk-otel-js.tgz` Node.js package with - `npm`. For example: + the following commands (requires `npm`): ```sh - sudo npm install --global /usr/lib/splunk-instrumentation/splunk-otel-js.tgz + sudo mkdir -p /usr/lib/splunk-instrumentation/splunk-otel-js && \ + cd /usr/lib/splunk-instrumentation/splunk-otel-js && \ + sudo npm install /usr/lib/splunk-instrumentation/splunk-otel-js.tgz ``` > **Notes:** - > - Ensure that all Node.js applications/services to be instrumented have - > access to the installation path of the Node.js package. + > - The default configuration files expect the Node.js package to be + > installed in the `/usr/lib/splunk-instrumentation/splunk-otel-js` + > directory. If installing the Node.js package globally or in a different + > directory, update the path for `NODE_OPTIONS` in the configuration files + > accordingly. > - On `arm64` architectures, it may be necessary to build/compile the > Node.js package when installing with `npm`. Ensure that any required > tools/libraries are installed on these systems, for example, diff --git a/instrumentation/README.md b/instrumentation/README.md index 7dee81f90f..9388a9b68f 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -71,7 +71,7 @@ The following methods are supported to manually activate and configure Auto Inst ``` - `/etc/splunk/zeroconfig/node.conf`: ``` - NODE_OPTIONS=-r @splunk/otel/instrument + NODE_OPTIONS=-r /usr/lib/splunk-instrumentation/splunk-otel-js/node_modules/@splunk/otel/instrument ``` Configuration of the respective agents is supported by the adding/updating the following environment variables in each of these files (***any environment variable not in this list will be ignored***): @@ -113,7 +113,7 @@ The following methods are supported to manually activate and configure Auto Inst ``` - Node.js: ``` - DefaultEnvironment="NODE_OPTIONS=-r @splunk/otel/instrument" + DefaultEnvironment="NODE_OPTIONS=-r /usr/lib/splunk-instrumentation/splunk-otel-js/node_modules/@splunk/otel/instrument" ``` 2. To configure the activated agents, add/update [`DefaultEnvironment`]( https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html#DefaultEnvironment=) within the target file diff --git a/instrumentation/packaging/fpm/etc/splunk/zeroconfig/node.conf b/instrumentation/packaging/fpm/etc/splunk/zeroconfig/node.conf index 139418d771..4d6e0c10bf 100644 --- a/instrumentation/packaging/fpm/etc/splunk/zeroconfig/node.conf +++ b/instrumentation/packaging/fpm/etc/splunk/zeroconfig/node.conf @@ -1 +1 @@ -NODE_OPTIONS=-r @splunk/otel/instrument +NODE_OPTIONS=-r /usr/lib/splunk-instrumentation/splunk-otel-js/node_modules/@splunk/otel/instrument diff --git a/instrumentation/packaging/fpm/examples/systemd/00-splunk-otel-auto-instrumentation.conf b/instrumentation/packaging/fpm/examples/systemd/00-splunk-otel-auto-instrumentation.conf index 5199d821e6..7367c9eaf5 100644 --- a/instrumentation/packaging/fpm/examples/systemd/00-splunk-otel-auto-instrumentation.conf +++ b/instrumentation/packaging/fpm/examples/systemd/00-splunk-otel-auto-instrumentation.conf @@ -42,7 +42,7 @@ DefaultEnvironment="JAVA_TOOL_OPTIONS=-javaagent:/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar" # Required to activate Splunk OpenTelemetry Auto Instrumentation for Node.js -DefaultEnvironment="NODE_OPTIONS=-r @splunk/otel/instrument" +DefaultEnvironment="NODE_OPTIONS=-r /usr/lib/splunk-instrumentation/splunk-otel-js/node_modules/@splunk/otel/instrument" # Examples of common configuration options. # The environment variables defined in this file will apply to all activated agents. diff --git a/internal/buildscripts/packaging/installer/install.sh b/internal/buildscripts/packaging/installer/install.sh index 0acd86580a..521bafe781 100755 --- a/internal/buildscripts/packaging/installer/install.sh +++ b/internal/buildscripts/packaging/installer/install.sh @@ -122,6 +122,7 @@ enable_metrics="false" java_zeroconfig_path="/etc/splunk/zeroconfig/java.conf" node_zeroconfig_path="/etc/splunk/zeroconfig/node.conf" node_package_path="/usr/lib/splunk-instrumentation/splunk-otel-js.tgz" +node_install_prefix="/usr/lib/splunk-instrumentation/splunk-otel-js" repo_for_stage() { local repo_url=$1 @@ -307,6 +308,7 @@ ensure_not_installed() { local with_fluentd="$1" local with_instrumentation="$2" local with_systemd_instrumentation="$3" + local npm_path="$4" local otelcol_path=$( command -v otelcol 2>/dev/null || true ) local td_agent_path=$( command -v td-agent 2>/dev/null || true ) @@ -333,8 +335,8 @@ ensure_not_installed() { echo "Please uninstall auto instrumentation, or try running this script with the '--uninstall' option." >&2 exit 1 fi - if command -v npm >/dev/null 2>&1 && npm ls --global @splunk/otel >/dev/null 2>&1; then - echo "The @splunk/otel npm package is already globally installed." >&2 + if [ -n "$npm_path" ] && (cd $node_install_prefix && $npm_path ls @splunk/otel >/dev/null 2>&1); then + echo "The @splunk/otel npm package is already installed in $node_install_prefix." >&2 echo "Please uninstall @splunk/otel, or try running this script with the '--uninstall' option." >&2 exit 1 fi @@ -543,7 +545,7 @@ EOH } install_node_package() { - local npm_command="$1" + local npm_path="$1" if [ "$distro_arch" = "arm64" ] || [ "$distro_arch" = "aarch64" ]; then echo "Installing dependencies for the Node.js Auto Instrumentation package ..." @@ -566,8 +568,9 @@ install_node_package() { fi echo "Installing the Node.js Auto Instrumentation package ..." - echo "Running '$npm_command $node_package_path':" - $npm_command $node_package_path + mkdir -p $node_install_prefix + echo "Running 'cd $node_install_prefix && $npm_path install $node_package_path':" + (cd $node_install_prefix && $npm_path install $node_package_path) } create_zeroconfig_node() { @@ -583,7 +586,7 @@ create_zeroconfig_node() { echo "Creating ${node_zeroconfig_path}" cat < $node_zeroconfig_path -NODE_OPTIONS=-r @splunk/otel/instrument +NODE_OPTIONS=-r ${node_install_prefix}/node_modules/@splunk/otel/instrument OTEL_RESOURCE_ATTRIBUTES=${resource_attributes} SPLUNK_PROFILER_ENABLED=${enable_profiler} SPLUNK_PROFILER_MEMORY_ENABLED=${enable_profiler_memory} @@ -630,7 +633,7 @@ EOH fi if [ "$with_node" = "true" ]; then - echo "DefaultEnvironment=\"NODE_OPTIONS=-r @splunk/otel/instrument\"" >> $systemd_instrumentation_config_path + echo "DefaultEnvironment=\"NODE_OPTIONS=-r ${node_install_prefix}/node_modules/@splunk/otel/instrument\"" >> $systemd_instrumentation_config_path fi systemctl daemon-reload @@ -785,9 +788,9 @@ uninstall() { fi done - if command -v npm >/dev/null 2>&1 && npm ls --global @splunk/otel >/dev/null 2>&1; then - npm uninstall --global @splunk/otel - echo "Successfully uninstalled the @splunk/otel npm package" + if command -v npm >/dev/null 2>&1 && (cd $node_install_prefix && npm ls @splunk/otel >/dev/null 2>&1); then + (cd $node_install_prefix && npm uninstall @splunk/otel) + echo "Successfully uninstalled the @splunk/otel npm package from $node_install_prefix" fi } @@ -878,15 +881,12 @@ Auto Instrumentation: for example "--with-instrumentation-sdk java". (default: --with-instrumentation-sdk "java,node" if --with-instrumentation or --with-systemd-instrumentation is also specified) - --npm-command "" If Auto Instrumentation for Node.js is enabled, npm is required to install the - included Splunk OpenTelemetry Auto Instrumentation for Node.js package with the - following command: - npm install --global - Use this option to specify a custom command (with quotes), for example: - --npm-command "/path/to/npm install --prefix /my/custom/directory" - *Note*: If npm is not in the user's PATH or if installation fails, - Auto Instrumentation for Node.js will not be enabled. - (default: "npm install --global") + --npm-path If Auto Instrumentation for Node.js is enabled, npm is required to install the + included Splunk OpenTelemetry Auto Instrumentation for Node.js package. If npm + is not found via the 'command -v npm' shell command or if installation fails, + Auto Instrumentation for Node.js will not be activated. Use this option to + specify a custom path to npm, for example "/my/path/to/npm". + (default: npm) --deployment-environment Set the 'deployment.environment' resource attribute to the specified value. If not specified, the "Environment" in the Splunk APM UI will appear as "unknown" for the auto instrumented application(s). @@ -1086,7 +1086,7 @@ parse_args_and_install() { local otlp_endpoint="" local with_java_instrumentation="true" local with_node_instrumentation="true" - local npm_command="" + local npm_path="" local node_package_installed="false" while [ -n "${1-}" ]; do @@ -1228,8 +1228,12 @@ parse_args_and_install() { done shift 1 ;; - --npm-command) - npm_command="$2" + --npm-path) + npm_path="$2" + if ! command -v "$npm_path" >/dev/null 2>&1; then + echo "[ERROR] $npm_path not found!" >&2 + exit 1 + fi shift 1 ;; --instrumentation-version) @@ -1359,10 +1363,8 @@ parse_args_and_install() { fi if [ "$with_node_instrumentation" = "true" ]; then - if [ -z "$npm_command" ]; then - if command -v npm >/dev/null 2>&1; then - npm_command="npm install --global" - fi + if [ -z "$npm_path" ] && command -v npm >/dev/null 2>&1; then + npm_path="npm" fi fi @@ -1380,7 +1382,7 @@ parse_args_and_install() { check_support - ensure_not_installed "$with_fluentd" "$with_instrumentation" "$with_systemd_instrumentation" + ensure_not_installed "$with_fluentd" "$with_instrumentation" "$with_systemd_instrumentation" "$npm_path" echo "Splunk OpenTelemetry Collector Version: ${collector_version}" if [ -n "$ballast" ]; then @@ -1443,11 +1445,11 @@ parse_args_and_install() { rm -f "$java_zeroconfig_path" fi if [ "$with_node_instrumentation" = "true" ]; then - if [ -n "$npm_command" ] && install_node_package "$npm_command"; then + if [ -n "$npm_path" ] && install_node_package "$npm_path"; then node_package_installed="true" create_zeroconfig_node "$otlp_endpoint" fi - if [ -z "$npm_command" ] || [ "$node_package_installed" = "false" ]; then + if [ -z "$npm_path" ] || [ "$node_package_installed" = "false" ]; then backup_file "$node_zeroconfig_path" rm -f "$node_zeroconfig_path" fi @@ -1467,7 +1469,7 @@ parse_args_and_install() { # remove libsplunk.so from /etc/ld.so.preload if it was added automatically by the instrumentation package disable_preload if [ "$with_node_instrumentation" = "true" ] && [ -f "$node_package_path" ]; then - if install_node_package "$npm_command"; then + if install_node_package "$npm_path"; then node_package_installed="true" fi fi @@ -1692,7 +1694,7 @@ EOH fi fi if [ "$with_node_instrumentation" = "true" ] && [ -f "$node_package_path" ]; then - if [ -z "$npm_command" ]; then + if [ -z "$npm_path" ]; then cat <