diff --git a/.github/ISSUE_TEMPLATE/1-bug-report.yml b/.github/ISSUE_TEMPLATE/1-bug-report.yml
deleted file mode 100644
index 496d06d3ad7..00000000000
--- a/.github/ISSUE_TEMPLATE/1-bug-report.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: 🐛 Bug report
-description: Create a report to help us improve
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for reporting an issue.
-
- This issue tracker is for bugs and issues found within Node.js core.
- If you require more general support please file an issue on our help repo. https://github.com/nodejs/help
-
- Please fill in as much of the following form as you're able.
- - type: input
- attributes:
- label: Version
- description: Output of `node -v`
- - type: input
- attributes:
- label: Platform
- description: |
- UNIX: output of `uname -a`
- Windows: output of `"$([Environment]::OSVersion.VersionString) $(('x86', 'x64')[[Environment]::Is64BitOperatingSystem])"` in PowerShell console
- - type: input
- attributes:
- label: Subsystem
- description: If known, please specify affected core module name
- - type: textarea
- attributes:
- label: What steps will reproduce the bug?
- description: Enter details about your bug, preferably a simple code snippet that can be run using `node` directly without installing third-party dependencies.
- - type: textarea
- attributes:
- label: How often does it reproduce? Is there a required condition?
- - type: textarea
- attributes:
- label: What is the expected behavior? Why is that the expected behavior?
- description: If possible please provide textual output instead of screenshots.
- - type: textarea
- attributes:
- label: What do you see instead?
- description: If possible please provide textual output instead of screenshots.
- validations:
- required: true
- - type: textarea
- attributes:
- label: Additional information
- description: Tell us anything else you think we should know.
diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.yml b/.github/ISSUE_TEMPLATE/2-feature-request.yml
deleted file mode 100644
index 26a77a3617c..00000000000
--- a/.github/ISSUE_TEMPLATE/2-feature-request.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: 🚀 Feature request
-description: Suggest an idea for this project
-labels: [feature request]
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for suggesting an idea to make Node.js better.
-
- Please fill in as much of the following form as you're able.
-
- For more information on how the project manages feature
- requests, see [Feature request management](https://github.com/nodejs/node/blob/HEAD/doc/contributing/feature-request-management.md).
- - type: textarea
- attributes:
- label: What is the problem this feature will solve?
- validations:
- required: true
- - type: textarea
- attributes:
- label: What is the feature you are proposing to solve the problem?
- validations:
- required: true
- - type: textarea
- attributes:
- label: What alternatives have you considered?
diff --git a/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.yml b/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.yml
deleted file mode 100644
index 753e2d9e58a..00000000000
--- a/.github/ISSUE_TEMPLATE/3-api-ref-docs-problem.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: 📗 Open an issue regarding the Node.js API reference docs
-description: Let us know about any problematic API reference documents
-labels: [doc]
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for wanting to make nodejs.org better!
-
- Please fill in as much of the following form as you're able.
- - type: input
- attributes:
- label: Affected URL(s)
- - type: textarea
- attributes:
- label: Description of the problem
- validations:
- required: true
diff --git a/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.yml b/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.yml
deleted file mode 100644
index 8dc099fb40a..00000000000
--- a/.github/ISSUE_TEMPLATE/4-report-a-flaky-test.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-name: Report a flaky test
-description: Report a flaky test in our CI
-labels: [flaky-test]
-body:
- - type: markdown
- attributes:
- value: |
- Thank you for reporting a flaky test.
-
- Flaky tests are tests that fail occasionally in the Node.js CI, but not
- consistently enough to block PRs from landing, or that are failing in CI
- jobs or test modes that are not run for every PR.
-
- Please fill in as much of the form below as you're able.
- - type: input
- attributes:
- label: Test
- description: The test that is flaky.
- placeholder: e.g. `test-fs-stat-bigint`
- validations:
- required: true
- - type: dropdown
- attributes:
- label: Platform
- description: The platform the test is flaky on.
- multiple: true
- options:
- - AIX
- - FreeBSD
- - Linux ARM64
- - Linux ARMv7
- - Linux PPC64LE
- - Linux s390x
- - Linux x64
- - macOS ARM64
- - macOS x64
- - SmartOS
- - Windows
- - Other
- - type: textarea
- attributes:
- label: Console output
- description: >
- A pasted console output from a failed CI job showing the whole failure
- of the test.
- render: console
- - type: textarea
- attributes:
- label: Build links
- description: Links to builds affected by the flaky test.
- value: '- '
- - type: textarea
- attributes:
- label: Additional information
- description: >
- If any investigation has been done, please include any information
- found, such as how consistently the test fails, whether the failure
- could be reproduced locally, when the test started failing, or anything
- else you think is relevant.
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
deleted file mode 100644
index df5f12bb934..00000000000
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-blank_issues_enabled: true
-contact_links:
- - name: ⁉️ Need help with Node.js?
- url: https://github.com/nodejs/help
- about: Please file an issue in our help repo.
- - name: 🌐 Found a problem with nodejs.org beyond the API reference docs?
- url: https://github.com/nodejs/nodejs.org/issues/new/choose
- about: Please file an issue in the Node.js website repo.
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
index 9e4a041bf7c..c80d1ee3a15 100644
--- a/.github/SUPPORT.md
+++ b/.github/SUPPORT.md
@@ -1,26 +1,28 @@
# Support
-Node.js contributors have limited availability to address general support
-questions. Please make sure you are using a [currently-supported version of
-Node.js](https://github.com/nodejs/Release#release-schedule).
+N|Solid contributors have limited availability to address general support
+questions. Please make sure you are using a currently supported version of
+N|Solid, which follows the same schedule from [Node.js](https://github.com/nodejs/Release#release-schedule).
When looking for support, please first search for your question in these venues:
-* [Node.js Website](https://nodejs.org/en/), especially the
- [API docs](https://nodejs.org/api/)
-* [Node.js Help](https://github.com/nodejs/help)
-* [Open or closed issues in the Node.js GitHub organization](https://github.com/issues?utf8=%E2%9C%93&q=sort%3Aupdated-desc+org%3Anodejs+is%3Aissue)
-
-If you didn't find an answer in the resources above, try these unofficial
-resources:
-
-* [Questions tagged 'node.js' on Stack Overflow](https://stackoverflow.com/questions/tagged/node.js)
-* [#node.js channel on libera.chat](https://web.libera.chat?channels=node.js&uio=d4)
-* [Node.js Slack Community](https://node-js.slack.com/)
- * To register: [nodeslackers.com](https://www.nodeslackers.com/)
+* [NodeSource Website](https://nodesource.com/), especially the
+ [Documentation site](https://docs.nodesource.com/)
+* [Open or closed issues in the N|Solid GitHub repository](https://github.com/nodesource/nsolid/issues)
+* [Questions tagged 'nsolid' on Stack Overflow](https://stackoverflow.com/questions/tagged/nsolid)
GitHub issues are for tracking enhancements and bugs, not general support.
-The open source license grants you the freedom to use Node.js. It does not
+The open-source license grants you the freedom to use N|Solid. It does not
guarantee commitments of other people's time. Please be respectful and manage
your expectations.
+
+## Professional Support Offering
+
+NodeSource offers professional support services for N|Solid, helping companies
+establish and sustain enterprise-grade N|Solid applications and services. The
+support extends from installation and configuration to upgrades, troubleshooting,
+and performance tuning, empowering teams to build and manage highly performant
+and reliable applications. Different levels of engagement are available to
+augment your development and operation teams, keeping your project on track when
+it matters most. For more details, visit [NodeSource Support](https://nodesource.com/services/support).
diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
index 4770dca2f28..2f14412848b 100644
--- a/.github/workflows/linters.yml
+++ b/.github/workflows/linters.yml
@@ -131,23 +131,6 @@ jobs:
run: |
make lint-py-build
make lint-py
- lint-yaml:
- if: github.event.pull_request.draft == false
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- with:
- persist-credentials: false
- - name: Use Python ${{ env.PYTHON_VERSION }}
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
- with:
- python-version: ${{ env.PYTHON_VERSION }}
- - name: Environment Information
- run: npx envinfo
- - name: Lint YAML
- run: |
- make lint-yaml-build || true
- make lint-yaml
lint-sh:
if: github.event.pull_request.draft == false
@@ -159,16 +142,6 @@ jobs:
- run: shellcheck -V
- name: Lint Shell scripts
run: tools/lint-sh.mjs .
- lint-codeowners:
- if: github.event.pull_request.draft == false
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- with:
- persist-credentials: false
- - uses: mszostok/codeowners-validator@7f3f5e28c6d7b8dfae5731e54ce2272ca384592f
- with:
- checks: files,duppatterns
lint-pr-url:
if: ${{ github.event.pull_request }}
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 79920931ce4..ad502f1348f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -166,3 +166,9 @@ __pycache__
# === Rules for C++ development ===
compile_commands.json
+# NSolid specifics
+/nsolid
+/nsolid_g
+# Ignore asserts-cpp and nlohmann paths in src/
+src/asserts-cpp/
+src/nlohmann/
diff --git a/BUILDING.md b/BUILDING.md
index e608aa318f8..34b3e31db2a 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -1,11 +1,11 @@
-# Building Node.js
+# Building N|Solid
Depending on what platform or features you need, the build process may
differ. After you've built a binary, running the
test suite to confirm that the binary works as intended is a good next step.
If you can reproduce a test failure, search for it in the
-[Node.js issue tracker](https://github.com/nodejs/node/issues) or
+[N|Solid issue tracker](https://github.com/nodesource/nsolid/issues) or
file a new issue.
## Table of contents
@@ -18,13 +18,13 @@ file a new issue.
* [Official binary platforms and toolchains](#official-binary-platforms-and-toolchains)
* [OpenSSL asm support](#openssl-asm-support)
* [Previous versions of this document](#previous-versions-of-this-document)
-* [Building Node.js on supported platforms](#building-nodejs-on-supported-platforms)
+* [Building N|Solid on supported platforms](#building-nsolid-on-supported-platforms)
* [Note about Python](#note-about-python)
* [Unix and macOS](#unix-and-macos)
* [Unix prerequisites](#unix-prerequisites)
* [macOS prerequisites](#macos-prerequisites)
- * [Building Node.js](#building-nodejs-1)
- * [Installing Node.js](#installing-nodejs)
+ * [Building N|Solid](#building-nsolid-1)
+ * [Installing N|Solid](#installing-nsolid)
* [Running Tests](#running-tests)
* [Running Coverage](#running-coverage)
* [Building the documentation](#building-the-documentation)
@@ -36,7 +36,7 @@ file a new issue.
* [Prerequisites](#prerequisites)
* [Option 1: Manual install](#option-1-manual-install)
* [Option 2: Automated install with Boxstarter](#option-2-automated-install-with-boxstarter)
- * [Building Node.js](#building-nodejs-2)
+ * [Building N|Solid](#building-nsolid-2)
* [Android](#android)
* [`Intl` (ECMA-402) support](#intl-ecma-402-support)
* [Build with full ICU support (all locales supported by ICU)](#build-with-full-icu-support-all-locales-supported-by-icu)
@@ -53,11 +53,11 @@ file a new issue.
* [Unix/macOS](#unixmacos-3)
* [Windows](#windows-4)
* [Configuring OpenSSL config appname](#configure-openssl-appname)
-* [Building Node.js with FIPS-compliant OpenSSL](#building-nodejs-with-fips-compliant-openssl)
-* [Building Node.js with external core modules](#building-nodejs-with-external-core-modules)
+* [Building N|Solid with FIPS-compliant OpenSSL](#building-nsolid-with-fips-compliant-openssl)
+* [Building N|Solid with external core modules](#building-nsolid-with-external-core-modules)
* [Unix/macOS](#unixmacos-4)
* [Windows](#windows-5)
-* [Note for downstream distributors of Node.js](#note-for-downstream-distributors-of-nodejs)
+* [Note for downstream distributors of N|Solid](#note-for-downstream-distributors-of-nsolid)
## Supported platforms
@@ -66,17 +66,17 @@ which it belongs.
### Input
-Node.js relies on V8 and libuv. We adopt a subset of their supported platforms.
+N|Solid relies on V8 and libuv. We adopt a subset of their supported platforms.
### Strategy
There are three support tiers:
-* **Tier 1**: These platforms represent the majority of Node.js users. The
- Node.js Build Working Group maintains infrastructure for full test coverage.
+* **Tier 1**: These platforms represent the majority of N|Solid users. The
+ N|Solid Build Working Group maintains infrastructure for full test coverage.
Test failures on tier 1 platforms will block releases.
-* **Tier 2**: These platforms represent smaller segments of the Node.js user
- base. The Node.js Build Working Group maintains infrastructure for full test
+* **Tier 2**: These platforms represent smaller segments of the N|Solid user
+ base. The N|Solid Build Working Group maintains infrastructure for full test
coverage. Test failures on tier 2 platforms will block releases.
Infrastructure issues may delay the release of binaries for these platforms.
* **Experimental**: May not compile or test suite may not pass. The core team
@@ -89,25 +89,25 @@ will reflect those changes.
### Platform list
-Node.js compilation/execution support depends on operating system, architecture,
+N|Solid compilation/execution support depends on operating system, architecture,
and libc version. The table below lists the support tier for each supported
combination. A list of [supported compile toolchains](#supported-toolchains) is
also supplied for tier 1 platforms.
-**For production applications, run Node.js on supported platforms only.**
+**For production applications, run N|Solid on supported platforms only.**
-Node.js does not support a platform version if a vendor has expired support
-for it. In other words, Node.js does not support running on End-of-Life (EoL)
+N|Solid does not support a platform version if a vendor has expired support
+for it. In other words, N|Solid does not support running on End-of-Life (EoL)
platforms. This is true regardless of entries in the table below.
| Operating System | Architectures | Versions | Support Type | Notes |
| ---------------- | ---------------- | --------------------------------- | ----------------------------------------------- | ------------------------------------ |
| GNU/Linux | x64 | kernel >= 4.18[^1], glibc >= 2.28 | Tier 1 | e.g. Ubuntu 20.04, Debian 10, RHEL 8 |
| GNU/Linux | x64 | kernel >= 3.10, musl >= 1.1.19 | Experimental | e.g. Alpine 3.8 |
-| GNU/Linux | x86 | kernel >= 3.10, glibc >= 2.17 | Experimental | Downgraded as of Node.js 10 |
+| GNU/Linux | x86 | kernel >= 3.10, glibc >= 2.17 | Experimental | Downgraded as of N\|Solid 10 |
| GNU/Linux | arm64 | kernel >= 4.18[^1], glibc >= 2.28 | Tier 1 | e.g. Ubuntu 20.04, Debian 10, RHEL 8 |
| GNU/Linux | armv7 | kernel >= 4.18[^1], glibc >= 2.28 | Tier 1 | e.g. Ubuntu 20.04, Debian 11 |
-| GNU/Linux | armv6 | kernel >= 4.14, glibc >= 2.24 | Experimental | Downgraded as of Node.js 12 |
+| GNU/Linux | armv6 | kernel >= 4.14, glibc >= 2.24 | Experimental | Downgraded as of N\|Solid 12 |
| GNU/Linux | ppc64le >=power8 | kernel >= 4.18[^1], glibc >= 2.28 | Tier 2 | e.g. Ubuntu 20.04, RHEL 8 |
| GNU/Linux | s390x | kernel >= 4.18[^1], glibc >= 2.28 | Tier 2 | e.g. RHEL 8 |
| Windows | x64, x86 (WoW64) | >= Windows 10/Server 2016 | Tier 1 | [^2],[^3] |
@@ -120,14 +120,14 @@ platforms. This is true regardless of entries in the table below.
| AIX | ppc64be >=power8 | >= 7.2 TL04 | Tier 2 | |
| FreeBSD | x64 | >= 12.4 | Experimental | |
-[^1]: Older kernel versions may work. However official Node.js release
+[^1]: Older kernel versions may work. However official N|Solid release
binaries are [built on RHEL 8 systems](#official-binary-platforms-and-toolchains)
with kernel 4.18.
-[^2]: On Windows, running Node.js in Windows terminal emulators
+[^2]: On Windows, running N|Solid in Windows terminal emulators
like `mintty` requires the usage of [winpty](https://github.com/rprichard/winpty)
- for the tty channels to work (e.g. `winpty node.exe script.js`).
- In "Git bash" if you call the node shell alias (`node` without the `.exe`
+ for the tty channels to work (e.g. `winpty nsolid.exe script.js`).
+ In "Git bash" if you call the nsolid shell alias (`nsolid` without the `.exe`
extension), `winpty` is used automatically.
[^3]: The Windows Subsystem for Linux (WSL) is not
@@ -135,10 +135,10 @@ platforms. This is true regardless of entries in the table below.
community will only address issues that reproduce on native GNU/Linux
systems. Issues that only reproduce on WSL should be reported in the
[WSL issue tracker](https://github.com/Microsoft/WSL/issues). Running the
- Windows binary (`node.exe`) in WSL will not work without workarounds such as
- stdio redirection.
+ Windows binary (`nsolid.exe`) in WSL will not work without workarounds such
+ as stdio redirection.
-[^4]: Running Node.js on x86 Windows should work and binaries
+[^4]: Running N|Solid on x86 Windows should work and binaries
are provided. However, tests in our infrastructure only run on WoW64.
Furthermore, compiling on x86 Windows is Experimental and
may not be possible.
@@ -158,7 +158,7 @@ Depending on the host platform, the selection of toolchains may vary.
### Official binary platforms and toolchains
-Binaries at are produced on:
+Binaries at are produced on:
| Binary package | Platform and Toolchain |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- |
@@ -207,21 +207,11 @@ Please refer to
If compiling without one of the above, use `configure` with the
`--openssl-no-asm` flag. Otherwise, `configure` will fail.
-### Previous versions of this document
-
-Supported platforms and toolchains change with each major version of Node.js.
-This document is only valid for the current major version of Node.js.
-Consult previous versions of this document for older versions of Node.js:
-
-* [Node.js 19](https://github.com/nodejs/node/blob/v19.x/BUILDING.md)
-* [Node.js 18](https://github.com/nodejs/node/blob/v18.x/BUILDING.md)
-* [Node.js 16](https://github.com/nodejs/node/blob/v16.x/BUILDING.md)
-
-## Building Node.js on supported platforms
+## Building N|Solid on supported platforms
### Note about Python
-The Node.js project supports Python >= 3 for building and testing.
+The N|Solid project supports Python >= 3 for building and testing.
### Unix and macOS
@@ -254,12 +244,12 @@ installed, you can find them under the menu `Xcode -> Open Developer Tool ->
More Developer Tools...`. This step will install `clang`, `clang++`, and
`make`.
-#### Building Node.js
+#### Building N|Solid
If the path to your build directory contains a space, the build will likely
fail.
-To build Node.js:
+To build N|Solid:
```bash
./configure
@@ -268,7 +258,7 @@ make -j4
We can speed up the builds by using [Ninja](https://ninja-build.org/). For more
information, see
-[Building Node.js with Ninja](doc/contributing/building-node-with-ninja.md).
+[Building N|Solid with Ninja](doc/contributing/building-nsolid-with-ninja.md).
The `-j4` option will cause `make` to run 4 simultaneous compilation jobs which
may reduce build time. For more information, see the
@@ -281,16 +271,16 @@ After building, setting up [firewall rules](tools/macos-firewall.sh) can avoid
popups asking to accept incoming network connections when running tests.
Running the following script on macOS will add the firewall rules for the
-executable `node` in the `out` directory and the symbolic `node` link in the
+executable `nsolid` in the `out` directory and the symbolic `nsolid` link in the
project's root directory.
```bash
sudo ./tools/macos-firewall.sh
```
-#### Installing Node.js
+#### Installing N|Solid
-To install this version of Node.js into a system directory:
+To install this version of N|Solid into a system directory:
```bash
[sudo] make install
@@ -349,13 +339,13 @@ tools/test.py --help
> Note: On Windows you should use `python3` executable.
> Example: `python3 tools/test.py test/message`
-You can usually run tests directly with node:
+You can usually run tests directly with nsolid:
```bash
-./node test/parallel/test-stream2-transform.js
+./nsolid test/parallel/test-stream2-transform.js
```
-> Info: `./node` points to your local Node.js build.
+> Info: `./nsolid` points to your local N|Solid build.
Remember to recompile with `make -j4` in between test runs if you change code in
the `lib` or `src` directories.
@@ -424,22 +414,22 @@ make coverage-clean
To build the documentation:
-This will build Node.js first (if necessary) and then use it to build the docs:
+This will build N|Solid first (if necessary) and then use it to build the docs:
```bash
make doc
```
-If you have an existing Node.js build, you can build just the docs with:
+If you have an existing N|Solid build, you can build just the docs with:
```bash
-NODE=/path/to/node make doc-only
+NODE=/path/to/nsolid make doc-only
```
To read the man page:
```bash
-man doc/node.1
+man doc/nsolid.1
```
If you prefer to read the full documentation in a browser, run the following.
@@ -461,10 +451,10 @@ make docopen
This will open a file URL to a one-page version of all the browsable HTML
documents using the default browser.
-To test if Node.js was built correctly:
+To test if N|Solid was built correctly:
```bash
-./node -e "console.log('Hello from Node.js ' + process.version)"
+./nsolid -e "console.log('Hello from N|Solid ' + process.version)"
```
#### Building a debug build
@@ -479,15 +469,15 @@ make -j4
```
`make` with `./configure --debug` generates two binaries, the regular release
-one in `out/Release/node` and a debug binary in `out/Debug/node`, only the
+one in `out/Release/nsolid` and a debug binary in `out/Debug/nsolid`, only the
release version is actually installed when you run `make install`.
To use the debug build with all the normal dependencies overwrite the release
version in the install directory:
```bash
-make install PREFIX=/opt/node-debug/
-cp -a -f out/Debug/node /opt/node-debug/node
+make install PREFIX=/opt/nsolid-debug/
+cp -a -f out/Debug/nsolid /opt/nsolid-debug/nsolid
```
When using the debug binary, core dumps will be generated in case of crashes.
@@ -495,14 +485,14 @@ These core dumps are useful for debugging when provided with the
corresponding original debug binary and system information.
Reading the core dump requires `gdb` built on the same platform the core dump
-was captured on (i.e. 64-bit `gdb` for `node` built on a 64-bit system, Linux
-`gdb` for `node` built on Linux) otherwise you will get errors like
+was captured on (i.e. 64-bit `gdb` for `nsolid` built on a 64-bit system, Linux
+`gdb` for `nsolid` built on Linux) otherwise you will get errors like
`not in executable format: File format not recognized`.
Example of generating a backtrace from the core dump:
```bash
-$ gdb /opt/node-debug/node core.node.8.1535359906
+$ gdb /opt/nsolid-debug/nsolid core.nsolid.8.1535359906
(gdb) backtrace
```
@@ -510,9 +500,6 @@ $ gdb /opt/node-debug/node core.node.8.1535359906
[ASan](https://github.com/google/sanitizers) can help detect various memory
related bugs. ASan builds are currently only supported on linux.
-If you want to check it on Windows or macOS or you want a consistent toolchain
-on Linux, you can try [Docker](https://www.docker.com/products/docker-desktop)
-(using an image like `gengjiawen/node-build:2020-02-14`).
The `--debug` is not necessary and will slow down build and testing, but it can
show clear stacktrace if ASan hits an issue.
@@ -524,7 +511,7 @@ make test-only
#### Speeding up frequent rebuilds when developing
-If you plan to frequently rebuild Node.js, especially if using several branches,
+If you plan to frequently rebuild N|Solid, especially if using several branches,
installing `ccache` can help to greatly reduce build times. Set up with:
On GNU/Linux:
@@ -572,7 +559,7 @@ to run it again before invoking `make -j4`.
#### Prerequisites
-##### Option 1: Manual install
+##### Manual install
* [Python 3.11](https://apps.microsoft.com/store/detail/python-311/9NRWMJP3717K)
* The "Desktop development with C++" workload from
@@ -600,40 +587,7 @@ Optional requirements for compiling for Windows 10 on ARM (ARM64):
* Visual C++ ATL for ARM64
* Windows 10 SDK 10.0.17763.0 or newer
-##### Option 2: Automated install with Boxstarter
-
-A [Boxstarter](https://boxstarter.org/) script can be used for easy setup of
-Windows systems with all the required prerequisites for Node.js development.
-This script will install the following [Chocolatey](https://chocolatey.org/)
-packages:
-
-* [Git for Windows](https://chocolatey.org/packages/git) with the `git` and
- Unix tools added to the `PATH`
-* [Python 3.x](https://chocolatey.org/packages/python)
-* [Visual Studio 2019 Build Tools](https://chocolatey.org/packages/visualstudio2019buildtools)
- with [Visual C++ workload](https://chocolatey.org/packages/visualstudio2019-workload-vctools)
-* [NetWide Assembler](https://chocolatey.org/packages/nasm)
-
-To install Node.js prerequisites using
-[Boxstarter WebLauncher](https://boxstarter.org/weblauncher), open
-
-with Internet Explorer or Edge browser on the target machine.
-
-Alternatively, you can use PowerShell. Run those commands from an elevated
-PowerShell terminal:
-
-```powershell
-Set-ExecutionPolicy Unrestricted -Force
-iex ((New-Object System.Net.WebClient).DownloadString('https://boxstarter.org/bootstrapper.ps1'))
-get-boxstarter -Force
-Install-BoxstarterPackage https://raw.githubusercontent.com/nodejs/node/HEAD/tools/bootstrap/windows_boxstarter -DisableReboots
-refreshenv
-```
-
-The entire installation using Boxstarter will take up approximately 10 GB of
-disk space.
-
-#### Building Node.js
+#### Building N|Solid
If the path to your build directory contains a space or a non-ASCII character,
the build will likely fail.
@@ -648,10 +602,10 @@ To run the tests:
.\vcbuild test
```
-To test if Node.js was built correctly:
+To test if N|Solid was built correctly:
```powershell
-Release\node -e "console.log('Hello from Node.js', process.version)"
+Release\nsolid -e "console.log('Hello from N|Solid', process.version)"
```
### Android
@@ -675,8 +629,8 @@ architecture supports \[arm, arm64/aarch64, x86, x86\_64].
## `Intl` (ECMA-402) support
-[Intl](https://github.com/nodejs/node/blob/HEAD/doc/api/intl.md) support is
-enabled by default.
+[Intl](https://github.com/nodesource/nsolid/blob/HEAD/doc/api/intl.md) support
+is enabled by default.
### Build with full ICU support (all locales supported by ICU)
@@ -781,10 +735,10 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)
### Configure OpenSSL appname
-Node.js can use an OpenSSL configuration file by specifying the environment
+N|Solid can use an OpenSSL configuration file by specifying the environment
variable `OPENSSL_CONF`, or using the command line option `--openssl-conf`, and
if none of those are specified will default to reading the default OpenSSL
-configuration file `openssl.cnf`. Node.js will only read a section that is by
+configuration file `openssl.cnf`. N|Solid will only read a section that is by
default named `nodejs_conf`, but this name can be overridden using the following
configure option:
@@ -792,19 +746,19 @@ configure option:
./configure --openssl-conf-name=
```
-## Building Node.js with FIPS-compliant OpenSSL
+## Building N|Solid with FIPS-compliant OpenSSL
-Node.js supports FIPS when statically or dynamically linked with OpenSSL 3 via
+N|Solid supports FIPS when statically or dynamically linked with OpenSSL 3 via
[OpenSSL's provider model](https://www.openssl.org/docs/man3.0/man7/crypto.html#OPENSSL-PROVIDERS).
-It is not necessary to rebuild Node.js to enable support for FIPS.
+It is not necessary to rebuild N|Solid to enable support for FIPS.
See [FIPS mode](./doc/api/crypto.md#fips-mode) for more information on how to
-enable FIPS support in Node.js.
+enable FIPS support in N|Solid.
-## Building Node.js with external core modules
+## Building N|Solid with external core modules
It is possible to specify one or more JavaScript text files to be bundled in
-the binary as built-in modules when building Node.js.
+the binary as built-in modules when building N|Solid.
### Unix/macOS
@@ -827,17 +781,17 @@ To make `./myModule.js` available via `require('myModule')` and
## Building to use shared dependencies at runtime
-By default Node.js is built so that all dependencies are bundled into
-the Node.js binary itself. This provides a single binary that includes
+By default N|Solid is built so that all dependencies are bundled into
+the N|Solid binary itself. This provides a single binary that includes
the correct versions of all dependencies on which it depends.
-Some Node.js distributions, however, prefer to manage dependencies.
+Some N|Solid distributions, however, prefer to manage dependencies.
A number of `configure` options are provided to support this use case.
* For dependencies with native code, the first set of options allow
- Node.js to be built so that it uses a shared library
+ N|Solid to be built so that it uses a shared library
at runtime instead of building and including the dependency
- in the Node.js binary itself. These options are in the
+ in the N|Solid binary itself. These options are in the
`Shared libraries` section of the `configure` help
(run `./configure --help` to get the complete list).
They provide the ability to enable the use of a shared library,
@@ -845,9 +799,9 @@ A number of `configure` options are provided to support this use case.
contain the include and shared library files.
* For dependencies with JavaScript code (including WASM), the second
- set of options allow the Node.js binary to be built so that it loads
+ set of options allow the N|Solid binary to be built so that it loads
the JavaScript for dependencies at runtime instead of being built into
- the Node.js binary itself. These options are in the `Shared builtins`
+ the N|Solid binary itself. These options are in the `Shared builtins`
section of the `configure` help
(run `./configure --help` to get the complete list). They
provide the ability to set the path to an external JavaScript file
@@ -857,22 +811,22 @@ It is the responsibility of any distribution
shipping with these options to:
* ensure that the shared dependencies available at runtime
- match what is expected by the Node.js binary. A
+ match what is expected by the N|Solid binary. A
mismatch may result in crashes or unexpected behavior.
-* fully test that Node.js operates as expected with the
+* fully test that N|Solid operates as expected with the
external dependencies. There may be little or no test coverage
- within the Node.js project CI for these non-default options.
+ within the N|Solid project CI for these non-default options.
-## Note for downstream distributors of Node.js
+## Note for downstream distributors of N|Solid
-The Node.js ecosystem is reliant on ABI compatibility within a major release.
-To maintain ABI compatibility it is required that distributed builds of Node.js
+The N|Solid ecosystem is reliant on ABI compatibility within a major release.
+To maintain ABI compatibility it is required that distributed builds of N|Solid
be built against the same version of dependencies, or similar versions that do
-not break their ABI compatibility, as those released by Node.js for any given
+not break their ABI compatibility, as those released by N|Solid for any given
`NODE_MODULE_VERSION` (located in `src/node_version.h`).
-When Node.js is built (with an intention to distribute) with an ABI
-incompatible with the official Node.js builds (e.g. using a ABI incompatible
+When N|Solid is built (with an intention to distribute) with an ABI
+incompatible with the official N|Solid builds (e.g. using a ABI incompatible
version of a dependency), please reserve and use a custom `NODE_MODULE_VERSION`
by opening a pull request against the registry available at
-.
+.
diff --git a/CHANGELOG_NSOLID.md b/CHANGELOG_NSOLID.md
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index d724027fd9a..0dbb63217bf 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,4 +1,69 @@
-# Code of Conduct
+# Contributor Code of Conduct
-* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md)
-* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/HEAD/Moderation-Policy.md)
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and
+expression, level of experience, education, socio-economic status, nationality,
+personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing a professional courtesy to everybody involved in the project
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others’ private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Maintainers are responsible for clarifying the standards of acceptable behavior
+and are expected to take appropriate and fair corrective action in response to
+any instances of unacceptable behavior.
+
+Maintainers have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, or to ban temporarily or permanently any
+contributor for other behaviors that they deem inappropriate, threatening,
+offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the NodeSource at
+. All complaints will be reviewed and investigated
+and will result in a response that is deemed necessary and appropriate
+to the circumstances. NodeSource is obligated to
+maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted
+separately.
+
+## Attribution
+
+This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
+available at
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f815adbb1fc..9bf2791a6a9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,32 +1,223 @@
-# Contributing to Node.js
+# Contributing to N|Solid
-* [Code of Conduct](#code-of-conduct)
-* [Issues](#issues)
-* [Pull Requests](#pull-requests)
-* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin)
+## [Code of Conduct](./CODE_OF_CONDUCT.md)
-## [Code of Conduct](./doc/contributing/code-of-conduct.md)
+The N|Solid project has a [Code of Conduct](./CODE_OF_CONDUCT.md) to which all
+contributors must adhere.
-The Node.js project has a
-[Code of Conduct](https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md)
-to which all contributors must adhere.
+## Issues and Pull Requests
-See [details on our policy on Code of Conduct](./doc/contributing/code-of-conduct.md).
+Issues can be filed on the GitHub issue tracker at
+.
-## [Issues](./doc/contributing/issues.md)
-
-* [Asking for General Help](./doc/contributing/issues.md#asking-for-general-help)
-* [Discussing non-technical topics](./doc/contributing/issues.md#discussing-non-technical-topics)
-* [Submitting a Bug Report](./doc/contributing/issues.md#submitting-a-bug-report)
-* [Triaging a Bug Report](./doc/contributing/issues.md#triaging-a-bug-report)
-
-## [Pull Requests](./doc/contributing/pull-requests.md)
+In order to build this project, you will need a build environment capable of
+building Node.js. See the included Node.js documentation for detailed
+instructions.
* [Dependencies](./doc/contributing/pull-requests.md#dependencies)
* [Setting up your local environment](./doc/contributing/pull-requests.md#setting-up-your-local-environment)
-* [The Process of Making Changes](./doc/contributing/pull-requests.md#the-process-of-making-changes)
-* [Reviewing Pull Requests](./doc/contributing/pull-requests.md#reviewing-pull-requests)
-* [Notes](./doc/contributing/pull-requests.md#notes)
+
+## Documentation
+
+* General [N|Solid Documentation](https://docs.nodesource.com/)
+* [Node.js API Documentation](https://nodejs.org/docs/latest/api/)
+
+## Releases
+
+This project aligns with the Node.js project's release schedule, albeit with
+its own versioning strategy. An N|Solid release corresponds with each Node.js
+LTS release but does not always increment the MAJOR version. The numbering is
+as follows:
+
+| Node.js Version | NSolid Version |
+| --------------- | --------------------------- |
+| v16.x.x | v4.x.x [^*] |
+| v18.x.x | v4.0.0-v4.10.2 [^*], v5.x.x |
+| v20.x.x | v5.x.x |
+| v22.x.x | v5.x.x |
+
+[^*]: Significant breaking changes or the introduction of substantial features
+ will drive the MAJOR version increments in N|Solid. Pre v5.0.0 versions of
+ N|Solid are proprietary, and there will be no further enhancements to these
+ closed versions.
+
+When there is a Node.js release, there will always be an associated N|Solid
+release. This typically is made within 24 hours of the upstream Node.js release.
+See the next section for more details on how the versions work and the
+implications in `git` branches. When these releases happen, both the Node.js
+version and the N|Solid version numbers will increase.
+
+There can be N|Solid releases independent of Node.js releases, but these are
+typically reserved for security releases or important N|Solid-specific bug
+fixes. When these releases are made, the N|Solid version number will increase
+(most likely a 'patch' version change), but the Node.js version number will stay
+the same.
+
+## N|Solid Version and branch strategy
+
+### Branching
+
+N|Solid development only happens on LTS versions. Once a future LTS version has
+been released, the next main N|Solid development branch will be created on top
+of the `vN.0.0` release of the future LTS branch.
+
+When a new `vN.0.0 LTS` is released, the N|Solid commits will be squashed from
+the latest release before the changes are landed on the latest tag. Reason is to
+simplify the change rebase. There would potentially be many breaking or
+conflicting commits that would need to be resolved which could take a lot of
+time with little advantage to tracking change history.
+
+The development branch's name will be `nsolid-vN.x` where `N` is the next
+version of N|Solid. Node.js v20.x is linked to N|Solid v5.x.
+
+The Node.js code will be merged into N|Solid's development branch at every tag.
+No rebasing will be done once the development branch for a given LTS line has
+been cut. This will help maintain the full history of all changes of the
+development branch and minimize the effort of rebasing a full set of changes
+every release. Below is an example graph of what it would look like having
+merged two tags into the development branch:
+
+```bash
+ * 6fdae3941eb (HEAD -> nsolid-v6.x) src: fix implementation details
+ * 97ffda657cf (tag: v20.6.0) 2023-08-XX, Version 20.6.0 (Current)
+ |\
+ | * 00fc8bb8b3d doc: add rluvaton to collaborators
+ | * fab6f58edf8 Working on v20.5.2
+ * | 4bfbe7e1800 Merge tag 'v20.5.1' into nsolid-oss-iron
+ |\|
+ | * 9f51c55a477 (tag: v20.5.1) 2023-08-09, Version 20.5.1 (Current)
+ | * 7337d214840 policy: handle Module.constructor and main.extensions bypass
+ * | f244610e4a7 agents: add linting for statsd agent
+ * | 04b25fa21a9 deps: move statsd_agent to agents folder
+```
+
+If fixes are required to merge a Node.js tag, then a merge branch is created in
+which the patch fixes land. The merge branch is then merged into the development
+branch. The reason for this is so that a bisect can always have passing tests,
+and all test failures will be within the merging branch.
+
+### Choosing A Branch For Your Changes
+
+Active development is done on the development branch of the latest (active) LTS
+version. For the initial N|Solid open source release, this branch was
+`nsolid-v5.x`. Prior to releases, relevant changes will be ported to the other
+(maintenance) LTS branch.
+
+### Releasing/Tagging
+
+Tags are created by combining the version of Node.js and N|Solid using the
+following pattern: `v+ns`. A typical tag might
+look like this: `v20.9.0+ns5.0.0`. N|Solid versioning adheres to semantic
+versioning (semver) principles.
+
+N|Solid versions will not automatically increment the MAJOR version with every
+Node.js LTS release. Instead, a MAJOR version increment in N|Solid will only
+occur when there are significant breaking changes or new, important features
+introduced in N|Solid.
+
+The adjustments in the N|Solid version are influenced by the Node.js version
+updates. For instance, if Node.js updates only involve a PATCH, then N|Solid
+will similarly restrict its modifications to what would be deemed a PATCH
+change, ensuring consistency and stability.
+
+Unscheduled security updates in Node.js won't precipitate additional
+alterations in N|Solid, facilitating swift deployment and maximum compatibility
+during such critical updates.
+
+When Node.js receives a PATCH version update, the corresponding N|Solid release
+branch will originate from the last N|Solid release. Necessary patch
+modifications will then be selectively incorporated from the development branch
+to the N|Solid release branch.
+
+Post the creation of a PATCH version's release branch in Node.js, the version
+of Node.js will be integrated into the N|Solid release branch, ensuring
+synchronization and continuity.
+
+Occasionally, N|Solid might have releases that do not align with Node.js
+releases. Such occurrences are rare and usually pertain to urgent PATCH
+releases addressing crucial issues in N|Solid. N|Solid strives to align its
+feature releases as closely as possible with the Node.js release schedule,
+promoting harmony and predictability in the release cycles.
+
+## Technical Priorities
+
+The N|Solid project aims to extend Node.js functionality to provide a unified
+access point for access for infrastructure and developer tooling for
+introspection and management of Node.js processes. It aims to collect, process,
+and export data with the lightest possible overhead and contention with the
+main Node.js process behavior.
+
+Priorities:
+
+* Minimal overhead and resource contention
+* Enhancing visibility into Node.js process, `libuv`, and `V8` activity
+* Centralized collection, processing, and dispatch from a separate isolated
+ thread
+* Additional introspection functionality added to any internal components
+* Enhanced security, data privacy, reliability, or performance
+* Secure 2-way communication for live-debugging or low-footprint interrogation
+* Support for standard infrastructure tools and functionality (logging, service
+ rotation)
+
+## Does a change belong in N|Solid or Node.js?
+
+We welcome collaboration and contribution, but please bear in mind the
+priorities of the project, as these will determine the chances of your changes
+being accepted. Fixes or supplemental changes to existing N|Solid behavior are
+the most likely to see acceptance. Changes to Node.js internal behaviors are
+generally going to require a much stronger case for addition to this project. In
+all cases, the final decision to include a feature or not is up to the core
+N|Solid team.
+
+This project aims to keep the Node.js API as intact and 100% compatible as
+possible. It is not a project aimed at working around the Node.js change
+process, and proposed changes that will conflict with that compatibility are
+almost certain to be rejected. It aims to add supplemental functionality with
+the specific purpose of achieving the above technical priorities. These should
+not interfere with the expected functionality of Node.js, except in the case of
+stricter modes that must be enabled via the N|Solid API.
+
+This project follows Node.js and if a feature from N|Solid becomes conflicting
+with the upstream Node.js project, the standing decision is to adopt the
+upstream Node.js solution. These sorts of changes have always been semver MAJOR
+changes and allow N|Solid to also make breaking changes to its own API if
+necessary to adopt upstream API changes.
+
+This alone should suggest the ideal target for a feature aimed at the entire
+Node.js audience is the Node.js project. If your feature lands there, it will
+land here when the feature is part of a Node.js LTS release.
+
+Belongs in Node.js:
+
+* Features or Fixes to Node.js API functionality.
+
+Belongs in N|Solid:
+
+* Features or Fixes that target N|Solid-specific functionality
+* Changes to Node.js behavior enabled via the N|Solid API
+
+### Features or Fixes that target N|Solid-specific functionality
+
+The N|Solid API aims to allow for extensions of functionality that target our
+audience with the aforementioned priorities in mind. Examples might include
+adding new metrics or tracing functionalities that use the N|Solid agent for
+collection and transport, or adding additional metrics export endpoint types, or
+fixes/changes to existing N|Solid behaviors.
+
+### Changes to Node.js behavior enabled via the N|Solid API
+
+The potential scope of the types of Node.js API changes is quite wide, but it is
+also the least likely to land. These should have stricter functionality than
+Node.js core behavior, and must be enabled by the N|Solid API.
+
+The potential scope for a change like this would be something that immediately
+enhances security or reliability but would require a semver major API change in
+Node.js. A past example was zero-filling Buffers during allocation prior to the
+`Buffer.alloc` upstream Node.js API changes. The N|Solid feature was removed in
+versions of Node.js with safe Buffer allocation.
+
+This type of change has a lot of potential, but also faces the biggest uphill
+battle towards becoming a part of the project.
diff --git a/GOVERNANCE.md b/GOVERNANCE.md
index 6ba1ef2daf2..e0f75aeee38 100644
--- a/GOVERNANCE.md
+++ b/GOVERNANCE.md
@@ -1,3 +1,7 @@
+> \[!IMPORTANT]
+> This document is from and refers to the upstream Node.js project.
+> See [CONTRIBUTING](CONTRIBUTING.md) for specific N|Solid content.
+
# Node.js Project Governance
diff --git a/LICENSE_NSOLID b/LICENSE_NSOLID
new file mode 100644
index 00000000000..8ea4925c0e9
--- /dev/null
+++ b/LICENSE_NSOLID
@@ -0,0 +1,545 @@
+# NodeSource N|Solid Runtime
+
+MIT License
+
+Copyright (c) 2023 NodeSource
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+## N|Solid includes multiple Open Source works:
+
+### Node.js: See included LICENSE
+________________
+
+
+### libcurl: https://curl.se/docs/copyright.html
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2023, Daniel Stenberg, , and many
+contributors, see the THANKS file.
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright
+notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
+
+
+________________
+
+
+### nlohmann json: MIT -- https://github.com/nlohmann/json/blob/develop/LICENSE.MIT
+
+
+MIT License
+
+Copyright (c) 2013-2022 Niels Lohmann
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
+________________
+
+
+### opentelemetry-cpp: Apache License 2.0 -- https://github.com/open-telemetry/opentelemetry-cpp/blob/main/LICENSE
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+________________
+
+
+### protobuf: https://github.com/protocolbuffers/protobuf/blob/main/LICENSE
+
+Copyright 2008 Google Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it. This code is not
+standalone and requires a support library to be linked with it. This
+support library is itself covered by the above license.
+
+
+________________
+
+
+### libsodium: ISC -- https://github.com/jedisct1/libsodium/blob/master/LICENSE
+
+/*
+ * ISC License
+ *
+ * Copyright (c) 2013-2023
+ * Frank Denis
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+________________
+
+
+### libzmq: LGPLv3 -- https://raw.githubusercontent.com/zeromq/libzmq/v4.3.4/COPYING.LESSER
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
+--------------------------------------------------------------------------------
+
+ SPECIAL EXCEPTION GRANTED BY COPYRIGHT HOLDERS
+
+As a special exception, copyright holders give you permission to link this
+library with independent modules to produce an executable, regardless of
+the license terms of these independent modules, and to copy and distribute
+the resulting executable under terms of your choice, provided that you also
+meet, for each linked independent module, the terms and conditions of
+the license of that module. An independent module is a module which is not
+derived from or based on this library. If you modify this library, you must
+extend this exception to your version of the library.
+
+Note: this exception relieves you of any obligations under sections 4 and 5
+of this license, and section 6 of the GNU General Public License.
+
+________________
diff --git a/Makefile b/Makefile
index b7871bf2185..ca595dcdce0 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ SIGN ?=
PREFIX ?= /usr/local
FLAKY_TESTS ?= run
TEST_CI_ARGS ?=
-STAGINGSERVER ?= node-www
+STAGINGSERVER ?= nsolid-staging
LOGLEVEL ?= silent
OSTYPE := $(shell uname -s | tr '[:upper:]' '[:lower:]')
ifeq ($(findstring os/390,$OSTYPE),os/390)
@@ -76,9 +76,9 @@ BUILDTYPE_LOWER := $(shell echo $(BUILDTYPE) | tr '[:upper:]' '[:lower:]')
EXEEXT := $(shell $(PYTHON) -c \
"import sys; print('.exe' if sys.platform == 'win32' else '')")
-NODE_EXE = node$(EXEEXT)
-NODE ?= ./$(NODE_EXE)
-NODE_G_EXE = node_g$(EXEEXT)
+NODE ?= ./nsolid$(EXEEXT)
+NODE_EXE = nsolid$(EXEEXT)
+NODE_G_EXE = nsolid_g$(EXEEXT)
NPM ?= ./deps/npm/bin/npm-cli.js
# Flags for packaging.
@@ -305,6 +305,7 @@ v8:
.PHONY: jstest
jstest: build-addons build-js-native-api-tests build-node-api-tests ## Runs addon tests and JS tests
+ NSOLID_DELAY_INIT="" \
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \
$(TEST_CI_ARGS) \
--skip-tests=$(CI_SKIP_TESTS) \
@@ -390,7 +391,8 @@ ADDONS_BINDING_SOURCES := \
ADDONS_PREREQS := config.gypi \
deps/npm/node_modules/node-gyp/package.json tools/build-addons.mjs \
deps/uv/include/*.h deps/v8/include/*.h \
- src/node.h src/node_buffer.h src/node_object_wrap.h src/node_version.h
+ src/node.h src/node_buffer.h src/node_object_wrap.h src/node_version.h \
+ src/nsolid.h src/nsolid/nsolid_api.h deps/nsuv/include/*.h
define run_build_addons
env npm_config_loglevel=$(LOGLEVEL) npm_config_nodedir="$$PWD" \
@@ -827,7 +829,7 @@ docclean:
$(RM) -r out/doc
$(RM) "$(VERSIONS_DATA)"
-RAWVER=$(shell $(PYTHON) tools/getnodeversion.py)
+RAWVER=$(shell $(PYTHON) tools/getnsolidversion.py)
VERSION=v$(RAWVER)
CHANGELOG=doc/changelogs/CHANGELOG_V$(firstword $(subst ., ,$(RAWVER))).md
@@ -973,7 +975,7 @@ ifeq ($(DESTCPU),ia32)
override DESTCPU=x86
endif
-TARNAME=node-$(FULLVERSION)
+TARNAME=nsolid-$(FULLVERSION)
TARBALL=$(TARNAME).tar
# Custom user-specified variation, use it directly
ifdef VARIATION
@@ -1141,15 +1143,15 @@ corepack-update:
.PHONY: pkg-upload
# Note: this is strictly for release builds on release machines only.
pkg-upload: pkg
- ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
+ ssh $(STAGINGSERVER) "mkdir -p staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)"
chmod 664 $(TARNAME).pkg
- scp -p $(TARNAME).pkg $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg.done"
+ scp -p $(TARNAME).pkg $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg.done"
$(TARBALL): release-only doc-only
git checkout-index -a -f --prefix=$(TARNAME)/
mkdir -p $(TARNAME)/doc/api
- cp doc/node.1 $(TARNAME)/doc/node.1
+ cp doc/nsolid.1 $(TARNAME)/doc/nsolid.1
cp -r out/doc/api/* $(TARNAME)/doc/api/
$(RM) -r $(TARNAME)/.editorconfig
$(RM) -r $(TARNAME)/.git*
@@ -1190,23 +1192,23 @@ tar: $(TARBALL) ## Create a source tarball.
.PHONY: tar-upload
# Note: this is strictly for release builds on release machines only.
tar-upload: tar
- ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
+ ssh $(STAGINGSERVER) "mkdir -p staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)"
chmod 664 $(TARNAME).tar.gz
- scp -p $(TARNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz.done"
+ scp -p $(TARNAME).tar.gz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz.done"
ifeq ($(XZ), 1)
chmod 664 $(TARNAME).tar.xz
- scp -p $(TARNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz.done"
+ scp -p $(TARNAME).tar.xz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz.done"
endif
.PHONY: doc-upload
# Note: this is strictly for release builds on release machines only.
doc-upload: doc
- ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/"
+ ssh $(STAGINGSERVER) "mkdir -p staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/docs/"
chmod -R ug=rw-x+X,o=r+X out/doc/
- scp -pr out/doc/* $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs/
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/docs.done"
+ scp -pr out/doc/* $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/docs/
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/docs.done"
.PHONY: $(TARBALL)-headers
$(TARBALL)-headers: release-only
@@ -1231,14 +1233,14 @@ tar-headers: $(TARBALL)-headers ## Build the node header tarball.
.PHONY: tar-headers-upload
tar-headers-upload: tar-headers
- ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
+ ssh $(STAGINGSERVER) "mkdir -p staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)"
chmod 664 $(TARNAME)-headers.tar.gz
- scp -p $(TARNAME)-headers.tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz.done"
+ scp -p $(TARNAME)-headers.tar.gz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.gz.done"
ifeq ($(XZ), 1)
chmod 664 $(TARNAME)-headers.tar.xz
- scp -p $(TARNAME)-headers.tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz.done"
+ scp -p $(TARNAME)-headers.tar.xz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-headers.tar.xz.done"
endif
$(BINARYTAR): release-only
@@ -1253,6 +1255,7 @@ $(BINARYTAR): release-only
$(MAKE) install DESTDIR=$(BINARYNAME) V=$(V) PORTABLE=1
cp README.md $(BINARYNAME)
cp LICENSE $(BINARYNAME)
+ cp LICENSE_NSOLID $(BINARYNAME)
ifeq ("$(wildcard $(CHANGELOG))","")
cp CHANGELOG.md $(BINARYNAME)
else
@@ -1276,14 +1279,14 @@ binary: $(BINARYTAR) ## Build release binary tarballs.
.PHONY: binary-upload
# Note: this is strictly for release builds on release machines only.
binary-upload: binary
- ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)"
+ ssh $(STAGINGSERVER) "mkdir -p staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)"
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
- scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done"
+ scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done"
ifeq ($(XZ), 1)
chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
- scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
- ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done"
+ scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz
+ ssh $(STAGINGSERVER) "touch staging/nsolid-node/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done"
endif
.PHONY: bench-all
@@ -1345,7 +1348,8 @@ format-md:
-LINT_JS_TARGETS = .eslintrc.js benchmark doc lib test tools
+LINT_JS_TARGETS = .eslintrc.js benchmark doc lib test tools \
+ agents/*/lib
run-lint-js = tools/node_modules/eslint/bin/eslint.js --cache \
--max-warnings=0 --report-unused-disable-directives $(LINT_JS_TARGETS)
@@ -1389,10 +1393,19 @@ LINT_CPP_ADDON_DOC_FILES = $(wildcard $(LINT_CPP_ADDON_DOC_FILES_GLOB))
LINT_CPP_EXCLUDE ?=
LINT_CPP_EXCLUDE += src/node_root_certs.h
LINT_CPP_EXCLUDE += $(LINT_CPP_ADDON_DOC_FILES)
+LINT_CPP_EXCLUDE += $(wildcard test/js-native-api/??_*/*.cc test/js-native-api/??_*/*.h test/node-api/??_*/*.cc test/node-api/??_*/*.h)
+LINT_CPP_EXCLUDE += src/asserts-cpp/asserts.h
+LINT_CPP_EXCLUDE += src/nlohmann/json.h
# These files were copied more or less verbatim from V8.
LINT_CPP_EXCLUDE += src/tracing/trace_event.h src/tracing/trace_event_common.h
LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \
+ agents/otlp/src/*.cc \
+ agents/otlp/src/*.h \
+ agents/statsd/src/*.cc \
+ agents/statsd/src/*.h \
+ agents/zmq/src/*.cc \
+ agents/zmq/src/*.h \
benchmark/napi/*/*.cc \
src/*.c \
src/*.cc \
@@ -1416,6 +1429,12 @@ LINT_CPP_FILES = $(filter-out $(LINT_CPP_EXCLUDE), $(wildcard \
tools/code_cache/*.h \
tools/snapshot/*.cc \
tools/snapshot/*.h \
+ deps/nsolid_cpu_profiler/bindings/*.cc \
+ deps/nsolid_cpu_profiler/src/*.cc \
+ deps/nsolid_cpu_profiler/include/*.h \
+ deps/nsolid_heap_profiler/bindings/*.cc \
+ deps/nsolid_heap_profiler/src/*.cc \
+ deps/nsolid_heap_profiler/include/*.h \
))
FORMAT_CPP_FILES ?=
@@ -1563,6 +1582,23 @@ lint-clean:
$(RM) tools/.*lintstamp
$(RM) .eslintcache
+.PHONY: get-nsolid-version
+get-nsolid-version:
+ @$(PYTHON) ./tools/getnsolidversion.py
+
+.PHONY: test-with-console
+test-with-console: export NSOLID_COMMAND = localhost:9001
+test-with-console:
+ @$(NODE) ./tools/check-for-console.js
+ $(MAKE) build-addons
+ $(MAKE) build-js-native-api-tests
+ $(MAKE) build-node-api-tests
+ # This is broken and won't allow testing to continue.
+ #$(MAKE) cctest
+ $(MAKE) jstest
+ $(MAKE) tooltest
+
+
HAS_DOCKER ?= $(shell command -v docker > /dev/null 2>&1; [ $$? -eq 0 ] && echo 1 || echo 0)
.PHONY: gen-openssl
diff --git a/README.md b/README.md
index a9eafa7595e..afe647a4399 100644
--- a/README.md
+++ b/README.md
@@ -1,863 +1,52 @@
-# Node.js
+# N|Solid
-Node.js is an open-source, cross-platform JavaScript runtime environment.
+N|Solid is an open-source, cross-platform JavaScript runtime environment based
+on the Node.js Runtime.
-For information on using Node.js, see the [Node.js website][].
-
-The Node.js project uses an [open governance model](./GOVERNANCE.md). The
-[OpenJS Foundation][] provides support for the project.
-
-Contributors are expected to act in a collaborative manner to move
-the project forward. We encourage the constructive exchange of contrary
-opinions and compromise. The [TSC](./GOVERNANCE.md#technical-steering-committee)
-reserves the right to limit or block contributors who repeatedly act in ways
-that discourage, exhaust, or otherwise negatively affect other participants.
-
-**This project has a [Code of Conduct][].**
-
-## Table of contents
-
-* [Support](#support)
-* [Release types](#release-types)
- * [Download](#download)
- * [Current and LTS releases](#current-and-lts-releases)
- * [Nightly releases](#nightly-releases)
- * [API documentation](#api-documentation)
- * [Verifying binaries](#verifying-binaries)
-* [Building Node.js](#building-nodejs)
-* [Security](#security)
-* [Contributing to Node.js](#contributing-to-nodejs)
-* [Current project team members](#current-project-team-members)
- * [TSC (Technical Steering Committee)](#tsc-technical-steering-committee)
- * [Collaborators](#collaborators)
- * [Triagers](#triagers)
- * [Release keys](#release-keys)
-* [License](#license)
+**This project has a [Code of Conduct](CODE_OF_CONDUCT.md).**
## Support
-Looking for help? Check out the
-[instructions for getting support](.github/SUPPORT.md).
-
-## Release types
-
-* **Current**: Under active development. Code for the Current release is in the
- branch for its major version number (for example,
- [v19.x](https://github.com/nodejs/node/tree/v19.x)). Node.js releases a new
- major version every 6 months, allowing for breaking changes. This happens in
- April and October every year. Releases appearing each October have a support
- life of 8 months. Releases appearing each April convert to LTS (see below)
- each October.
-* **LTS**: Releases that receive Long Term Support, with a focus on stability
- and security. Every even-numbered major version will become an LTS release.
- LTS releases receive 12 months of _Active LTS_ support and a further 18 months
- of _Maintenance_. LTS release lines have alphabetically-ordered code names,
- beginning with v4 Argon. There are no breaking changes or feature additions,
- except in some special circumstances.
-* **Nightly**: Code from the Current branch built every 24-hours when there are
- changes. Use with caution.
-
-Current and LTS releases follow [semantic versioning](https://semver.org). A
-member of the Release Team [signs](#release-keys) each Current and LTS release.
-For more information, see the
-[Release README](https://github.com/nodejs/Release#readme).
+Looking for help? You can contact us at or check out
+the [instructions for getting support](.github/SUPPORT.md).
### Download
Binaries, installers, and source tarballs are available at
-.
-
-#### Current and LTS releases
+.
-
-
-The [latest](https://nodejs.org/download/release/latest/) directory is an
-alias for the latest Current release. The latest-_codename_ directory is an
-alias for the latest release from an LTS line. For example, the
-[latest-hydrogen](https://nodejs.org/download/release/latest-hydrogen/)
-directory contains the latest Hydrogen (Node.js 18) release.
-
-#### Nightly releases
-
-
-
-Each directory name and filename contains a date (in UTC) and the commit
-SHA at the HEAD of the release.
+Our distribution channels can also be used to install N|Solid. See how at
+.
#### API documentation
+For N|Solid specific documentation visit .
+
Documentation for the latest Current release is at .
Version-specific documentation is available in each release directory in the
_docs_ subdirectory. Version-specific documentation is also at
.
-### Verifying binaries
-
-Download directories contain a `SHASUMS256.txt` file with SHA checksums for the
-files.
-
-To download `SHASUMS256.txt` using `curl`:
-
-```bash
-curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt
-```
+## Building N|Solid
-To check that a downloaded file matches the checksum, run
-it through `sha256sum` with a command such as:
-
-```bash
-grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c -
-```
-
-For Current and LTS, the GPG detached signature of `SHASUMS256.txt` is in
-`SHASUMS256.txt.sig`. You can use it with `gpg` to verify the integrity of
-`SHASUMS256.txt`. You will first need to import
-[the GPG keys of individuals authorized to create releases](#release-keys). To
-import the keys:
-
-```bash
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C
-```
-
-See [Release keys](#release-keys) for a script to import active release keys.
-
-Next, download the `SHASUMS256.txt.sig` for the release:
-
-```bash
-curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt.sig
-```
-
-Then use `gpg --verify SHASUMS256.txt.sig SHASUMS256.txt` to verify
-the file's signature.
-
-## Building Node.js
-
-See [BUILDING.md](BUILDING.md) for instructions on how to build Node.js from
+See [BUILDING.md](BUILDING.md) for instructions on how to build N|Solid from
source and a list of supported platforms.
## Security
-For information on reporting security vulnerabilities in Node.js, see
+For information on reporting security vulnerabilities in N|Solid, see
[SECURITY.md](./SECURITY.md).
-## Contributing to Node.js
-
-* [Contributing to the project][]
-* [Working Groups][]
-* [Strategic initiatives][]
-* [Technical values and prioritization][]
-
-## Current project team members
-
-For information about the governance of the Node.js project, see
-[GOVERNANCE.md](./GOVERNANCE.md).
-
-
-
-### TSC (Technical Steering Committee)
-
-#### TSC voting members
-
-
-
-* [aduh95](https://github.com/aduh95) -
- **Antoine du Hamel** <> (he/him)
-* [anonrig](https://github.com/anonrig) -
- **Yagiz Nizipli** <> (he/him)
-* [apapirovski](https://github.com/apapirovski) -
- **Anatoli Papirovski** <> (he/him)
-* [benjamingr](https://github.com/benjamingr) -
- **Benjamin Gruenbaum** <>
-* [BridgeAR](https://github.com/BridgeAR) -
- **Ruben Bridgewater** <> (he/him)
-* [cjihrig](https://github.com/cjihrig) -
- **Colin Ihrig** <> (he/him)
-* [danielleadams](https://github.com/danielleadams) -
- **Danielle Adams** <> (she/her)
-* [GeoffreyBooth](https://github.com/geoffreybooth) -
- **Geoffrey Booth** <> (he/him)
-* [gireeshpunathil](https://github.com/gireeshpunathil) -
- **Gireesh Punathil** <> (he/him)
-* [jasnell](https://github.com/jasnell) -
- **James M Snell** <> (he/him)
-* [joyeecheung](https://github.com/joyeecheung) -
- **Joyee Cheung** <> (she/her)
-* [legendecas](https://github.com/legendecas) -
- **Chengzhong Wu** <> (he/him)
-* [mcollina](https://github.com/mcollina) -
- **Matteo Collina** <> (he/him)
-* [mhdawson](https://github.com/mhdawson) -
- **Michael Dawson** <> (he/him)
-* [MoLow](https://github.com/MoLow) -
- **Moshe Atlow** <> (he/him)
-* [RafaelGSS](https://github.com/RafaelGSS) -
- **Rafael Gonzaga** <> (he/him)
-* [RaisinTen](https://github.com/RaisinTen) -
- **Darshan Sen** <> (he/him)
-* [richardlau](https://github.com/richardlau) -
- **Richard Lau** <>
-* [ronag](https://github.com/ronag) -
- **Robert Nagy** <>
-* [ruyadorno](https://github.com/ruyadorno) -
- **Ruy Adorno** <> (he/him)
-* [targos](https://github.com/targos) -
- **Michaël Zasso** <> (he/him)
-* [tniessen](https://github.com/tniessen) -
- **Tobias Nießen** <> (he/him)
-* [Trott](https://github.com/Trott) -
- **Rich Trott** <> (he/him)
-
-#### TSC regular members
-
-* [BethGriggs](https://github.com/BethGriggs) -
- **Beth Griggs** <> (she/her)
-* [bnoordhuis](https://github.com/bnoordhuis) -
- **Ben Noordhuis** <>
-* [ChALkeR](https://github.com/ChALkeR) -
- **Сковорода Никита Андреевич** <> (he/him)
-* [codebytere](https://github.com/codebytere) -
- **Shelley Vohr** <> (she/her)
-* [danbev](https://github.com/danbev) -
- **Daniel Bevenius** <> (he/him)
-* [fhinkel](https://github.com/fhinkel) -
- **Franziska Hinkelmann** <> (she/her)
-* [gabrielschulhof](https://github.com/gabrielschulhof) -
- **Gabriel Schulhof** <>
-* [mscdex](https://github.com/mscdex) -
- **Brian White** <>
-* [MylesBorins](https://github.com/MylesBorins) -
- **Myles Borins** <> (he/him)
-* [rvagg](https://github.com/rvagg) -
- **Rod Vagg** <>
-* [TimothyGu](https://github.com/TimothyGu) -
- **Tiancheng "Timothy" Gu** <> (he/him)
-
-
-
-TSC emeriti members
-
-#### TSC emeriti members
-
-* [addaleax](https://github.com/addaleax) -
- **Anna Henningsen** <> (she/her)
-* [chrisdickinson](https://github.com/chrisdickinson) -
- **Chris Dickinson** <>
-* [evanlucas](https://github.com/evanlucas) -
- **Evan Lucas** <> (he/him)
-* [Fishrock123](https://github.com/Fishrock123) -
- **Jeremiah Senkpiel** <> (he/they)
-* [gibfahn](https://github.com/gibfahn) -
- **Gibson Fahnestock** <> (he/him)
-* [indutny](https://github.com/indutny) -
- **Fedor Indutny** <>
-* [isaacs](https://github.com/isaacs) -
- **Isaac Z. Schlueter** <>
-* [joshgav](https://github.com/joshgav) -
- **Josh Gavant** <>
-* [mmarchini](https://github.com/mmarchini) -
- **Mary Marchini** <> (she/her)
-* [nebrius](https://github.com/nebrius) -
- **Bryan Hughes** <>
-* [ofrobots](https://github.com/ofrobots) -
- **Ali Ijaz Sheikh** <> (he/him)
-* [orangemocha](https://github.com/orangemocha) -
- **Alexis Campailla** <>
-* [piscisaureus](https://github.com/piscisaureus) -
- **Bert Belder** <>
-* [sam-github](https://github.com/sam-github) -
- **Sam Roberts** <>
-* [shigeki](https://github.com/shigeki) -
- **Shigeki Ohtsu** <> (he/him)
-* [thefourtheye](https://github.com/thefourtheye) -
- **Sakthipriyan Vairamani** <> (he/him)
-* [trevnorris](https://github.com/trevnorris) -
- **Trevor Norris** <>
-
-
-
-
-
-### Collaborators
-
-* [addaleax](https://github.com/addaleax) -
- **Anna Henningsen** <> (she/her)
-* [aduh95](https://github.com/aduh95) -
- **Antoine du Hamel** <> (he/him)
-* [anonrig](https://github.com/anonrig) -
- **Yagiz Nizipli** <> (he/him)
-* [antsmartian](https://github.com/antsmartian) -
- **Anto Aravinth** <> (he/him)
-* [apapirovski](https://github.com/apapirovski) -
- **Anatoli Papirovski** <> (he/him)
-* [AshCripps](https://github.com/AshCripps) -
- **Ash Cripps** <>
-* [atlowChemi](https://github.com/atlowChemi) -
- **Chemi Atlow** <> (he/him)
-* [Ayase-252](https://github.com/Ayase-252) -
- **Qingyu Deng** <>
-* [bengl](https://github.com/bengl) -
- **Bryan English** <> (he/him)
-* [benjamingr](https://github.com/benjamingr) -
- **Benjamin Gruenbaum** <>
-* [BethGriggs](https://github.com/BethGriggs) -
- **Beth Griggs** <> (she/her)
-* [bmeck](https://github.com/bmeck) -
- **Bradley Farias** <>
-* [bnb](https://github.com/bnb) -
- **Tierney Cyren** <> (they/he)
-* [bnoordhuis](https://github.com/bnoordhuis) -
- **Ben Noordhuis** <>
-* [BridgeAR](https://github.com/BridgeAR) -
- **Ruben Bridgewater** <> (he/him)
-* [cclauss](https://github.com/cclauss) -
- **Christian Clauss** <> (he/him)
-* [ChALkeR](https://github.com/ChALkeR) -
- **Сковорода Никита Андреевич** <> (he/him)
-* [cjihrig](https://github.com/cjihrig) -
- **Colin Ihrig** <> (he/him)
-* [codebytere](https://github.com/codebytere) -
- **Shelley Vohr** <> (she/her)
-* [cola119](https://github.com/cola119) -
- **Kohei Ueno** <> (he/him)
-* [daeyeon](https://github.com/daeyeon) -
- **Daeyeon Jeong** <> (he/him)
-* [danbev](https://github.com/danbev) -
- **Daniel Bevenius** <> (he/him)
-* [danielleadams](https://github.com/danielleadams) -
- **Danielle Adams** <> (she/her)
-* [debadree25](https://github.com/debadree25) -
- **Debadree Chatterjee** <> (he/him)
-* [deokjinkim](https://github.com/deokjinkim) -
- **Deokjin Kim** <> (he/him)
-* [devnexen](https://github.com/devnexen) -
- **David Carlier** <>
-* [devsnek](https://github.com/devsnek) -
- **Gus Caplan** <> (they/them)
-* [edsadr](https://github.com/edsadr) -
- **Adrian Estrada** <> (he/him)
-* [erickwendel](https://github.com/erickwendel) -
- **Erick Wendel** <> (he/him)
-* [fhinkel](https://github.com/fhinkel) -
- **Franziska Hinkelmann** <> (she/her)
-* [F3n67u](https://github.com/F3n67u) -
- **Feng Yu** <> (he/him)
-* [Flarna](https://github.com/Flarna) -
- **Gerhard Stöbich** <> (he/they)
-* [gabrielschulhof](https://github.com/gabrielschulhof) -
- **Gabriel Schulhof** <>
-* [gengjiawen](https://github.com/gengjiawen) -
- **Jiawen Geng** <>
-* [GeoffreyBooth](https://github.com/geoffreybooth) -
- **Geoffrey Booth** <> (he/him)
-* [gireeshpunathil](https://github.com/gireeshpunathil) -
- **Gireesh Punathil** <> (he/him)
-* [guybedford](https://github.com/guybedford) -
- **Guy Bedford** <> (he/him)
-* [HarshithaKP](https://github.com/HarshithaKP) -
- **Harshitha K P** <> (she/her)
-* [himself65](https://github.com/himself65) -
- **Zeyu "Alex" Yang** <> (he/him)
-* [iansu](https://github.com/iansu) -
- **Ian Sutherland** <>
-* [JacksonTian](https://github.com/JacksonTian) -
- **Jackson Tian** <>
-* [JakobJingleheimer](https://github.com/JakobJingleheimer) -
- **Jacob Smith** <> (he/him)
-* [jasnell](https://github.com/jasnell) -
- **James M Snell** <> (he/him)
-* [jkrems](https://github.com/jkrems) -
- **Jan Krems** <> (he/him)
-* [joesepi](https://github.com/joesepi) -
- **Joe Sepi** <> (he/him)
-* [joyeecheung](https://github.com/joyeecheung) -
- **Joyee Cheung** <> (she/her)
-* [juanarbol](https://github.com/juanarbol) -
- **Juan José Arboleda** <> (he/him)
-* [JungMinu](https://github.com/JungMinu) -
- **Minwoo Jung** <> (he/him)
-* [KhafraDev](https://github.com/KhafraDev) -
- **Matthew Aitken** <> (he/him)
-* [kuriyosh](https://github.com/kuriyosh) -
- **Yoshiki Kurihara** <> (he/him)
-* [kvakil](https://github.com/kvakil) -
- **Keyhan Vakil** <>
-* [legendecas](https://github.com/legendecas) -
- **Chengzhong Wu** <> (he/him)
-* [linkgoron](https://github.com/linkgoron) -
- **Nitzan Uziely** <>
-* [LiviaMedeiros](https://github.com/LiviaMedeiros) -
- **LiviaMedeiros** <>
-* [lpinca](https://github.com/lpinca) -
- **Luigi Pinca** <> (he/him)
-* [lukekarrys](https://github.com/lukekarrys) -
- **Luke Karrys** <> (he/him)
-* [Lxxyx](https://github.com/Lxxyx) -
- **Zijian Liu** <> (he/him)
-* [marco-ippolito](https://github.com/marco-ippolito) -
- **Marco Ippolito** <> (he/him)
-* [marsonya](https://github.com/marsonya) -
- **Akhil Marsonya** <> (he/him)
-* [mcollina](https://github.com/mcollina) -
- **Matteo Collina** <> (he/him)
-* [meixg](https://github.com/meixg) -
- **Xuguang Mei** <> (he/him)
-* [Mesteery](https://github.com/Mesteery) -
- **Mestery** <> (he/him)
-* [mhdawson](https://github.com/mhdawson) -
- **Michael Dawson** <> (he/him)
-* [miladfarca](https://github.com/miladfarca) -
- **Milad Fa** <> (he/him)
-* [mildsunrise](https://github.com/mildsunrise) -
- **Alba Mendez** <> (she/her)
-* [MoLow](https://github.com/MoLow) -
- **Moshe Atlow** <> (he/him)
-* [mscdex](https://github.com/mscdex) -
- **Brian White** <>
-* [MylesBorins](https://github.com/MylesBorins) -
- **Myles Borins** <> (he/him)
-* [ovflowd](https://github.com/ovflowd) -
- **Claudio Wunder** <> (he/they)
-* [oyyd](https://github.com/oyyd) -
- **Ouyang Yadong** <> (he/him)
-* [panva](https://github.com/panva) -
- **Filip Skokan** <> (he/him)
-* [Qard](https://github.com/Qard) -
- **Stephen Belanger** <> (he/him)
-* [RafaelGSS](https://github.com/RafaelGSS) -
- **Rafael Gonzaga** <> (he/him)
-* [RaisinTen](https://github.com/RaisinTen) -
- **Darshan Sen** <> (he/him)
-* [rluvaton](https://github.com/rluvaton) -
- **Raz Luvaton** <> (he/him)
-* [richardlau](https://github.com/richardlau) -
- **Richard Lau** <>
-* [rickyes](https://github.com/rickyes) -
- **Ricky Zhou** <<0x19951125@gmail.com>> (he/him)
-* [ronag](https://github.com/ronag) -
- **Robert Nagy** <>
-* [ruyadorno](https://github.com/ruyadorno) -
- **Ruy Adorno** <> (he/him)
-* [rvagg](https://github.com/rvagg) -
- **Rod Vagg** <>
-* [ryzokuken](https://github.com/ryzokuken) -
- **Ujjwal Sharma** <> (he/him)
-* [santigimeno](https://github.com/santigimeno) -
- **Santiago Gimeno** <>
-* [shisama](https://github.com/shisama) -
- **Masashi Hirano** <> (he/him)
-* [ShogunPanda](https://github.com/ShogunPanda) -
- **Paolo Insogna** <> (he/him)
-* [srl295](https://github.com/srl295) -
- **Steven R Loomis** <>
-* [sxa](https://github.com/sxa) -
- **Stewart X Addison** <> (he/him)
-* [targos](https://github.com/targos) -
- **Michaël Zasso** <> (he/him)
-* [theanarkh](https://github.com/theanarkh) -
- **theanarkh** <> (he/him)
-* [TimothyGu](https://github.com/TimothyGu) -
- **Tiancheng "Timothy" Gu** <> (he/him)
-* [tniessen](https://github.com/tniessen) -
- **Tobias Nießen** <> (he/him)
-* [trivikr](https://github.com/trivikr) -
- **Trivikram Kamat** <>
-* [Trott](https://github.com/Trott) -
- **Rich Trott** <> (he/him)
-* [vdeturckheim](https://github.com/vdeturckheim) -
- **Vladimir de Turckheim** <> (he/him)
-* [vmoroz](https://github.com/vmoroz) -
- **Vladimir Morozov** <> (he/him)
-* [VoltrexKeyva](https://github.com/VoltrexKeyva) -
- **Mohammed Keyvanzadeh** <> (he/him)
-* [watilde](https://github.com/watilde) -
- **Daijiro Wachi** <> (he/him)
-* [XadillaX](https://github.com/XadillaX) -
- **Khaidi Chu** <> (he/him)
-* [yashLadha](https://github.com/yashLadha) -
- **Yash Ladha** <> (he/him)
-* [ZYSzys](https://github.com/ZYSzys) -
- **Yongsheng Zhang** <> (he/him)
-
-
-
-Emeriti
-
-
-
-### Collaborator emeriti
-
-* [ak239](https://github.com/ak239) -
- **Aleksei Koziatinskii** <>
-* [andrasq](https://github.com/andrasq) -
- **Andras** <>
-* [AnnaMag](https://github.com/AnnaMag) -
- **Anna M. Kedzierska** <>
-* [AndreasMadsen](https://github.com/AndreasMadsen) -
- **Andreas Madsen** <> (he/him)
-* [aqrln](https://github.com/aqrln) -
- **Alexey Orlenko** <> (he/him)
-* [bcoe](https://github.com/bcoe) -
- **Ben Coe** <> (he/him)
-* [bmeurer](https://github.com/bmeurer) -
- **Benedikt Meurer** <>
-* [boneskull](https://github.com/boneskull) -
- **Christopher Hiller** <> (he/him)
-* [brendanashworth](https://github.com/brendanashworth) -
- **Brendan Ashworth** <>
-* [bzoz](https://github.com/bzoz) -
- **Bartosz Sosnowski** <>
-* [calvinmetcalf](https://github.com/calvinmetcalf) -
- **Calvin Metcalf** <>
-* [chrisdickinson](https://github.com/chrisdickinson) -
- **Chris Dickinson** <>
-* [claudiorodriguez](https://github.com/claudiorodriguez) -
- **Claudio Rodriguez** <>
-* [DavidCai1993](https://github.com/DavidCai1993) -
- **David Cai** <> (he/him)
-* [davisjam](https://github.com/davisjam) -
- **Jamie Davis** <> (he/him)
-* [digitalinfinity](https://github.com/digitalinfinity) -
- **Hitesh Kanwathirtha** <> (he/him)
-* [dmabupt](https://github.com/dmabupt) -
- **Xu Meng** <> (he/him)
-* [dnlup](https://github.com/dnlup)
- **dnlup** <>
-* [eljefedelrodeodeljefe](https://github.com/eljefedelrodeodeljefe) -
- **Robert Jefe Lindstaedt** <>
-* [estliberitas](https://github.com/estliberitas) -
- **Alexander Makarenko** <>
-* [eugeneo](https://github.com/eugeneo) -
- **Eugene Ostroukhov** <>
-* [evanlucas](https://github.com/evanlucas) -
- **Evan Lucas** <> (he/him)
-* [firedfox](https://github.com/firedfox) -
- **Daniel Wang** <>
-* [Fishrock123](https://github.com/Fishrock123) -
- **Jeremiah Senkpiel** <> (he/they)
-* [gdams](https://github.com/gdams) -
- **George Adams** <> (he/him)
-* [geek](https://github.com/geek) -
- **Wyatt Preul** <>
-* [gibfahn](https://github.com/gibfahn) -
- **Gibson Fahnestock** <> (he/him)
-* [glentiki](https://github.com/glentiki) -
- **Glen Keane** <> (he/him)
-* [hashseed](https://github.com/hashseed) -
- **Yang Guo** <> (he/him)
-* [hiroppy](https://github.com/hiroppy) -
- **Yuta Hiroto** <> (he/him)
-* [iarna](https://github.com/iarna) -
- **Rebecca Turner** <>
-* [imran-iq](https://github.com/imran-iq) -
- **Imran Iqbal** <>
-* [imyller](https://github.com/imyller) -
- **Ilkka Myller** <>
-* [indutny](https://github.com/indutny) -
- **Fedor Indutny** <>
-* [isaacs](https://github.com/isaacs) -
- **Isaac Z. Schlueter** <>
-* [italoacasas](https://github.com/italoacasas) -
- **Italo A. Casas** <> (he/him)
-* [jasongin](https://github.com/jasongin) -
- **Jason Ginchereau** <>
-* [jbergstroem](https://github.com/jbergstroem) -
- **Johan Bergström** <>
-* [jdalton](https://github.com/jdalton) -
- **John-David Dalton** <>
-* [jhamhader](https://github.com/jhamhader) -
- **Yuval Brik** <>
-* [joaocgreis](https://github.com/joaocgreis) -
- **João Reis** <>
-* [joshgav](https://github.com/joshgav) -
- **Josh Gavant** <>
-* [julianduque](https://github.com/julianduque) -
- **Julian Duque** <> (he/him)
-* [kfarnung](https://github.com/kfarnung) -
- **Kyle Farnung** <> (he/him)
-* [kunalspathak](https://github.com/kunalspathak) -
- **Kunal Pathak** <>
-* [lance](https://github.com/lance) -
- **Lance Ball** <> (he/him)
-* [Leko](https://github.com/Leko) -
- **Shingo Inoue** <> (he/him)
-* [lucamaraschi](https://github.com/lucamaraschi) -
- **Luca Maraschi** <> (he/him)
-* [lundibundi](https://github.com/lundibundi) -
- **Denys Otrishko** <> (he/him)
-* [lxe](https://github.com/lxe) -
- **Aleksey Smolenchuk** <>
-* [maclover7](https://github.com/maclover7) -
- **Jon Moss** <> (he/him)
-* [mafintosh](https://github.com/mafintosh) -
- **Mathias Buus** <> (he/him)
-* [matthewloring](https://github.com/matthewloring) -
- **Matthew Loring** <>
-* [micnic](https://github.com/micnic) -
- **Nicu Micleușanu** <> (he/him)
-* [mikeal](https://github.com/mikeal) -
- **Mikeal Rogers** <>
-* [misterdjules](https://github.com/misterdjules) -
- **Julien Gilli** <>
-* [mmarchini](https://github.com/mmarchini) -
- **Mary Marchini** <> (she/her)
-* [monsanto](https://github.com/monsanto) -
- **Christopher Monsanto** <>
-* [MoonBall](https://github.com/MoonBall) -
- **Chen Gang** <>
-* [not-an-aardvark](https://github.com/not-an-aardvark) -
- **Teddy Katz** <> (he/him)
-* [ofrobots](https://github.com/ofrobots) -
- **Ali Ijaz Sheikh** <> (he/him)
-* [Olegas](https://github.com/Olegas) -
- **Oleg Elifantiev** <>
-* [orangemocha](https://github.com/orangemocha) -
- **Alexis Campailla** <>
-* [othiym23](https://github.com/othiym23) -
- **Forrest L Norvell** <> (they/them/themself)
-* [petkaantonov](https://github.com/petkaantonov) -
- **Petka Antonov** <>
-* [phillipj](https://github.com/phillipj) -
- **Phillip Johnsen** <>
-* [piscisaureus](https://github.com/piscisaureus) -
- **Bert Belder** <>
-* [pmq20](https://github.com/pmq20) -
- **Minqi Pan** <>
-* [PoojaDurgad](https://github.com/PoojaDurgad) -
- **Pooja D P** <> (she/her)
-* [princejwesley](https://github.com/princejwesley) -
- **Prince John Wesley** <>
-* [psmarshall](https://github.com/psmarshall) -
- **Peter Marshall** <> (he/him)
-* [puzpuzpuz](https://github.com/puzpuzpuz) -
- **Andrey Pechkurov** <> (he/him)
-* [refack](https://github.com/refack) -
- **Refael Ackermann (רפאל פלחי)** <> (he/him/הוא/אתה)
-* [rexagod](https://github.com/rexagod) -
- **Pranshu Srivastava** <> (he/him)
-* [rlidwka](https://github.com/rlidwka) -
- **Alex Kocharin** <>
-* [rmg](https://github.com/rmg) -
- **Ryan Graham** <>
-* [robertkowalski](https://github.com/robertkowalski) -
- **Robert Kowalski** <>
-* [romankl](https://github.com/romankl) -
- **Roman Klauke** <>
-* [ronkorving](https://github.com/ronkorving) -
- **Ron Korving** <>
-* [RReverser](https://github.com/RReverser) -
- **Ingvar Stepanyan** <>
-* [rubys](https://github.com/rubys) -
- **Sam Ruby** <>
-* [saghul](https://github.com/saghul) -
- **Saúl Ibarra Corretgé** <>
-* [sam-github](https://github.com/sam-github) -
- **Sam Roberts** <>
-* [sebdeckers](https://github.com/sebdeckers) -
- **Sebastiaan Deckers** <>
-* [seishun](https://github.com/seishun) -
- **Nikolai Vavilov** <>
-* [shigeki](https://github.com/shigeki) -
- **Shigeki Ohtsu** <> (he/him)
-* [silverwind](https://github.com/silverwind) -
- **Roman Reiss** <>
-* [starkwang](https://github.com/starkwang) -
- **Weijia Wang** <>
-* [stefanmb](https://github.com/stefanmb) -
- **Stefan Budeanu** <>
-* [tellnes](https://github.com/tellnes) -
- **Christian Tellnes** <>
-* [thefourtheye](https://github.com/thefourtheye) -
- **Sakthipriyan Vairamani** <> (he/him)
-* [thlorenz](https://github.com/thlorenz) -
- **Thorsten Lorenz** <>
-* [trevnorris](https://github.com/trevnorris) -
- **Trevor Norris** <>
-* [tunniclm](https://github.com/tunniclm) -
- **Mike Tunnicliffe** <>
-* [vkurchatkin](https://github.com/vkurchatkin) -
- **Vladimir Kurchatkin** <>
-* [vsemozhetbyt](https://github.com/vsemozhetbyt) -
- **Vse Mozhet Byt** <> (he/him)
-* [watson](https://github.com/watson) -
- **Thomas Watson** <>
-* [whitlockjc](https://github.com/whitlockjc) -
- **Jeremy Whitlock** <>
-* [yhwang](https://github.com/yhwang) -
- **Yihong Wang** <>
-* [yorkie](https://github.com/yorkie) -
- **Yorkie Liu** <>
-* [yosuke-furukawa](https://github.com/yosuke-furukawa) -
- **Yosuke Furukawa** <>
-
-
-
-
-
-Collaborators follow the [Collaborator Guide](./doc/contributing/collaborator-guide.md) in
-maintaining the Node.js project.
-
-### Triagers
-
-* [atlowChemi](https://github.com/atlowChemi) -
- **Chemi Atlow** <> (he/him)
-* [Ayase-252](https://github.com/Ayase-252) -
- **Qingyu Deng** <>
-* [bmuenzenmeyer](https://github.com/bmuenzenmeyer) -
- **Brian Muenzenmeyer** <> (he/him)
-* [daeyeon](https://github.com/daeyeon) -
- **Daeyeon Jeong** <> (he/him)
-* [F3n67u](https://github.com/F3n67u) -
- **Feng Yu** <> (he/him)
-* [himadriganguly](https://github.com/himadriganguly) -
- **Himadri Ganguly** <> (he/him)
-* [iam-frankqiu](https://github.com/iam-frankqiu) -
- **Frank Qiu** <> (he/him)
-* [marsonya](https://github.com/marsonya) -
- **Akhil Marsonya** <> (he/him)
-* [meixg](https://github.com/meixg) -
- **Xuguang Mei** <> (he/him)
-* [mertcanaltin](https://github.com/mertcanaltin) -
- **Mert Can Altin** <>
-* [Mesteery](https://github.com/Mesteery) -
- **Mestery** <> (he/him)
-* [preveen-stack](https://github.com/preveen-stack) -
- **Preveen Padmanabhan** <> (he/him)
-* [PoojaDurgad](https://github.com/PoojaDurgad) -
- **Pooja Durgad** <>
-* [RaisinTen](https://github.com/RaisinTen) -
- **Darshan Sen** <>
-* [VoltrexKeyva](https://github.com/VoltrexKeyva) -
- **Mohammed Keyvanzadeh** <> (he/him)
-
-Triagers follow the [Triage Guide](./doc/contributing/issues.md#triaging-a-bug-report) when
-responding to new issues.
-
-### Release keys
-
-Primary GPG keys for Node.js Releasers (some Releasers sign with subkeys):
-
-* **Beth Griggs** <>
- `4ED778F539E3634C779C87C6D7062848A1AB005C`
-* **Bryan English** <>
- `141F07595B7B3FFE74309A937405533BE57C7D57`
-* **Danielle Adams** <>
- `74F12602B6F1C4E913FAA37AD3A89613643B6201`
-* **Juan José Arboleda** <>
- `DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7`
-* **Michaël Zasso** <>
- `8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600`
-* **Myles Borins** <>
- `C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8`
-* **RafaelGSS** <>
- `890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4`
-* **Richard Lau** <>
- `C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C`
-* **Ruy Adorno** <>
- `108F52B48DB57BB0CC439B2997B01419BD92F80A`
-* **Ulises Gascón** <>
- `A363A499291CBBC940DD62E41F10027AF002F8B0`
-
-To import the full set of trusted release keys (including subkeys possibly used
-to sign releases):
-
-```bash
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 4ED778F539E3634C779C87C6D7062848A1AB005C
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 141F07595B7B3FFE74309A937405533BE57C7D57
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 74F12602B6F1C4E913FAA37AD3A89613643B6201
-gpg --keyserver hkps://keys.openpgp.org --recv-keys DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600
-gpg --keyserver hkps://keys.openpgp.org --recv-keys C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4
-gpg --keyserver hkps://keys.openpgp.org --recv-keys C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C
-gpg --keyserver hkps://keys.openpgp.org --recv-keys 108F52B48DB57BB0CC439B2997B01419BD92F80A
-gpg --keyserver hkps://keys.openpgp.org --recv-keys A363A499291CBBC940DD62E41F10027AF002F8B0
-```
-
-See [Verifying binaries](#verifying-binaries) for how to use these keys to
-verify a downloaded file.
-
-
-
-Other keys used to sign some previous releases
-
-* **Chris Dickinson** <>
- `9554F04D7259F04124DE6B476D5A82AC7E37093B`
-* **Colin Ihrig** <>
- `94AE36675C464D64BAFA68DD7434390BDBE9B9C5`
-* **Danielle Adams** <>
- `1C050899334244A8AF75E53792EF661D867B9DFA`
-* **Evan Lucas** <>
- `B9AE9905FFD7803F25714661B63B535A4C206CA9`
-* **Gibson Fahnestock** <>
- `77984A986EBC2AA786BC0F66B01FBB92821C587A`
-* **Isaac Z. Schlueter** <>
- `93C7E9E91B49E432C2F75674B0A78B0A6C481CF6`
-* **Italo A. Casas** <>
- `56730D5401028683275BD23C23EFEFE93C4CFFFE`
-* **James M Snell** <>
- `71DCFD284A79C3B38668286BC97EC7A07EDE3FC1`
-* **Jeremiah Senkpiel** <>
- `FD3A5288F042B6850C66B31F09FE44734EB7990E`
-* **Juan José Arboleda** <>
- `61FC681DFB92A079F1685E77973F295594EC4689`
-* **Julien Gilli** <>
- `114F43EE0176B71C7BC219DD50A3051F888C628D`
-* **Rod Vagg** <>
- `DD8F2338BAE7501E3DD5AC78C273792F7D83545D`
-* **Ruben Bridgewater** <>
- `A48C2BEE680E841632CD4E44F07496B3EB3C1762`
-* **Shelley Vohr** <>
- `B9E2F5981AA6E0CD28160D9FF13993A75599653C`
-* **Timothy J Fontaine** <>
- `7937DFD2AB06298B2293C3187D33FF9D0246406D`
-
-
-
-### Security release stewards
-
-When possible, the commitment to take slots in the
-security release steward rotation is made by companies in order
-to ensure individuals who act as security stewards have the
-support and recognition from their employer to be able to
-prioritize security releases. Security release stewards manage security
-releases on a rotation basis as outlined in the
-[security release process](./doc/contributing/security-release-process.md).
+## Contributing to N|Solid
-* Datadog
- * [bengl](https://github.com/bengl) -
- **Bryan English** <> (he/him)
-* NearForm
- * [RafaelGSS](https://github.com/RafaelGSS) -
- **Rafael Gonzaga** <> (he/him)
-* NodeSource
- * [juanarbol](https://github.com/juanarbol) -
- **Juan José Arboleda** <> (he/him)
-* Platformatic
- * [mcollina](https://github.com/mcollina) -
- **Matteo Collina** <> (he/him)
-* Red Hat and IBM
- * [joesepi](https://github.com/joesepi) -
- **Joe Sepi** <> (he/him)
- * [mhdawson](https://github.com/mhdawson) -
- **Michael Dawson** <> (he/him)
+[Contributing to the project][]
## License
-Node.js is available under the
-[MIT license](https://opensource.org/licenses/MIT). Node.js also includes
-external libraries that are available under a variety of licenses. See
-[LICENSE](https://github.com/nodejs/node/blob/HEAD/LICENSE) for the full
-license text.
+N|Solid is available under the
+[MIT license](https://opensource.org/licenses/MIT). N|Solid also includes
+external libraries that are available under a variety of licenses. See
+[LICENSE](LICENSE) and [LICENSE\_NSOLID](LICENSE_NSOLID) for the full license
+text.
-[Code of Conduct]: https://github.com/nodejs/admin/blob/HEAD/CODE_OF_CONDUCT.md
[Contributing to the project]: CONTRIBUTING.md
-[Node.js website]: https://nodejs.org/
-[OpenJS Foundation]: https://openjsf.org/
-[Strategic initiatives]: doc/contributing/strategic-initiatives.md
-[Technical values and prioritization]: doc/contributing/technical-values.md
-[Working Groups]: https://github.com/nodejs/TSC/blob/HEAD/WORKING_GROUPS.md
diff --git a/SECURITY.md b/SECURITY.md
index 85c185df600..835402b1eec 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -1,8 +1,8 @@
# Security
-## Reporting a bug in Node.js
+## Reporting a security issue in N|Solid
-Report security bugs in Node.js via [HackerOne](https://hackerone.com/nodejs).
+Report security bugs in the N|Solid Runtime via
Normally your report will be acknowledged within 5 days, and you'll receive
a more detailed response to your report within 10 days indicating the
@@ -15,12 +15,6 @@ you informed of the progress being made towards a fix and full announcement,
and may ask for additional information or guidance surrounding the reported
issue.
-### Node.js bug bounty program
-
-The Node.js project engages in an official bug bounty program for security
-researchers and responsible public disclosures. The program is managed through
-the HackerOne platform. See for further details.
-
## Reporting a bug in a third party module
Security bugs in third party modules should be reported to their respective
@@ -28,192 +22,20 @@ maintainers.
## Disclosure policy
-Here is the security disclosure policy for Node.js
+Here is the security disclosure policy for N|Solid
* The security report is received and is assigned a primary handler. This
person will coordinate the fix and release process. The problem is validated
- against all supported Node.js versions. Once confirmed, a list of all affected
+ against all supported versions. Once confirmed, a list of all affected
versions is determined. Code is audited to find any potential similar
problems. Fixes are prepared for all supported releases.
These fixes are not committed to the public repository but rather held locally
pending the announcement.
-* A suggested embargo date for this vulnerability is chosen and a CVE (Common
- Vulnerabilities and Exposures (CVE®)) is requested for the vulnerability.
-
-* On the embargo date, the Node.js security mailing list is sent a copy of the
- announcement. The changes are pushed to the public repository and new builds
- are deployed to nodejs.org. Within 6 hours of the mailing list being
- notified, a copy of the advisory will be published on the Node.js blog.
-
-* Typically the embargo date will be set 72 hours from the time the CVE is
- issued. However, this may vary depending on the severity of the bug or
- difficulty in applying a fix.
-
-* This process can take some time, especially when coordination is required
- with maintainers of other projects. Every effort will be made to handle the
- bug in as timely a manner as possible; however, it's important that we follow
- the release process above to ensure that the disclosure is handled in a
- consistent manner.
-
-## The Node.js threat model
-
-In the Node.js threat model, there are trusted elements such as the
-underlying operating system. Vulnerabilities that require the compromise
-of these trusted elements are outside the scope of the Node.js threat
-model.
-
-For a vulnerability to be eligible for a bug bounty, it must be a
-vulnerability in the context of the Node.js threat model. In other
-words, it cannot assume that a trusted element (such as the operating
-system) has been compromised.
-
-Being able to cause the following through control of the elements that Node.js
-does not trust is considered a vulnerability:
-
-* Disclosure or loss of integrity or confidentiality of data protected through
- the correct use of Node.js APIs.
-* The unavailability of the runtime, including the unbounded degradation of its
- performance.
-
-If Node.js loads configuration files or runs code by default (without a
-specific request from the user), and this is not documented, it is considered a
-vulnerability.
-Vulnerabilities related to this case may be fixed by a documentation update.
-
-**Node.js does NOT trust**:
-
-1. Data received from the remote end of inbound network connections
- that are accepted through the use of Node.js APIs and
- which is transformed/validated by Node.js before being passed
- to the application. This includes:
- * HTTP APIs (all flavors) server APIs.
-2. The data received from the remote end of outbound network connections
- that are created through the use of Node.js APIs and
- which is transformed/validated by Node.js before being passed
- to the application EXCEPT in respect to payload length. Node.js trusts
- that applications make connections/requests which will avoid payload
- sizes that will result in a Denial of Service.
- * HTTP APIs (all flavors) client APIs.
- * DNS APIs.
-3. Consumers of data protected through the use of Node.js APIs (for example
- people who have access to data encrypted through the Node.js crypto APIs).
-4. The file content or other I/O that is opened for reading or writing by the
- use of Node.js APIs (ex: stdin, stdout, stderr).
-
-In other words, if the data passing through Node.js to/from the application
-can trigger actions other than those documented for the APIs, there is likely
-a security vulnerability. Examples of unwanted actions are polluting globals,
-causing an unrecoverable crash, or any other unexpected side effects that can
-lead to a loss of confidentiality, integrity, or availability.
-
-**Node.js trusts everything else**. As some examples this includes:
-
-1. The developers and infrastructure that runs it.
-2. The operating system that Node.js is running under and its configuration,
- along with anything under control of the operating system.
-3. The code it is asked to run including JavaScript and native code, even if
- said code is dynamically loaded, e.g. all dependencies installed from the
- npm registry.
- The code run inherits all the privileges of the execution user.
-4. Inputs provided to it by the code it is asked to run, as it is the
- responsibility of the application to perform the required input validations,
- e.g. the input to `JSON.parse()`.
-5. Any connection used for inspector (debugger protocol) regardless of being
- opened by command line options or Node.js APIs, and regardless of the remote
- end being on the local machine or remote.
-6. The file system when requiring a module.
- See .
-
-Any unexpected behavior from the data manipulation from Node.js Internal
-functions may be considered a vulnerability if they are exploitable via
-untrusted resources.
-
-In addition to addressing vulnerabilities based on the above, the project works
-to avoid APIs and internal implementations that make it "easy" for application
-code to use the APIs incorrectly in a way that results in vulnerabilities within
-the application code itself. While we don’t consider those vulnerabilities in
-Node.js itself and will not necessarily issue a CVE we do want them to be
-reported privately to Node.js first.
-We often choose to work to improve our APIs based on those reports and issue
-fixes either in regular or security releases depending on how much of a risk to
-the community they pose.
-
-### Examples of vulnerabilities
-
-#### Improper Certificate Validation (CWE-295)
-
-* Node.js provides APIs to validate handling of Subject Alternative Names (SANs)
- in certificates used to connect to a TLS/SSL endpoint. If certificates can be
- crafted which result in incorrect validation by the Node.js APIs that is
- considered a vulnerability.
-
-#### Inconsistent Interpretation of HTTP Requests (CWE-444)
-
-* Node.js provides APIs to accept http connections. Those APIs parse the
- headers received for a connection and pass them on to the application.
- Bugs in parsing those headers which can result in request smuggling are
- considered vulnerabilities.
-
-#### Missing Cryptographic Step (CWE-325)
-
-* Node.js provides APIs to encrypt data. Bugs that would allow an attacker
- to get the original data without requiring the decryption key are
- considered vulnerabilities.
-
-#### External Control of System or Configuration Setting (CWE-15)
-
-* If Node.js automatically loads a configuration file which is not documented
- and modification of that configuration can affect the confidentiality of
- data protected using the Node.js APIs this is considered a vulnerability.
-
-### Examples of non-vulnerabilities
-
-#### Malicious Third-Party Modules (CWE-1357)
-
-* Code is trusted by Node.js, therefore any scenario that requires a malicious
- third-party module cannot result in a vulnerability in Node.js.
-
-#### Prototype Pollution Attacks (CWE-1321)
-
-* Node.js trusts the inputs provided to it by application code.
- It is up to the application to sanitize appropriately, therefore any scenario
- that requires control over user input is not considered a vulnerability.
-
-#### Uncontrolled Search Path Element (CWE-427)
-
-* Node.js trusts the file system in the environment accessible to it.
- Therefore, it is not a vulnerability if it accesses/loads files from any path
- that is accessible to it.
-
-#### External Control of System or Configuration Setting (CWE-15)
-
-* If Node.js automatically loads a configuration file which is documented
- no scenario that requires modification of that configuration file is
- considered a vulnerability.
-
-#### Uncontrolled Resource Consumption (CWE-400) on outbound connections
-
-* If Node.js is asked to connect to a remote site and return an
- artifact, it is not considered a vulnerability if the size of
- that artifact is large enough to impact performance or
- cause the runtime to run out of resources.
-
-## Assessing experimental features reports
-
-Experimental features are eligible to reports as any other stable feature of
-Node.js. They will also be susceptible to receiving the same severity score
-as any other stable feature.
+* If deemed necessary, an embargo date may be set and a delayed announcement
+ may be coordinated to time the announcement with the release. Some NodeSource
+ customers may be invited to be a part of the embargo and review team.
## Receiving security updates
-Security notifications will be distributed via the following methods.
-
-*
-*
-
-## Comments on this policy
-
-If you have suggestions on how this process could be improved please submit a
-[pull request](https://github.com/nodejs/nodejs.org) or
-[file an issue](https://github.com/nodejs/security-wg/issues/new) to discuss.
+Security notifications will be distributed via
diff --git a/agents/.eslintrc.yaml b/agents/.eslintrc.yaml
new file mode 100644
index 00000000000..cc4fa197501
--- /dev/null
+++ b/agents/.eslintrc.yaml
@@ -0,0 +1,258 @@
+env:
+ es6: true
+
+rules:
+ prefer-object-spread: error
+ no-buffer-constructor: error
+ no-mixed-operators:
+ - error
+ - groups: [['&&', '||']]
+ no-restricted-syntax:
+ # Config copied from .eslintrc.js
+ - error
+ - selector: CallExpression[callee.object.name='assert']:not([callee.property.name='ok']):not([callee.property.name='fail']):not([callee.property.name='ifError'])
+ message: Please only use simple assertions in ./lib
+ - selector: CallExpression[callee.name='setTimeout'][arguments.length<2]
+ message: setTimeout() must be invoked with at least two arguments.
+ - selector: CallExpression[callee.name='setInterval'][arguments.length<2]
+ message: setInterval() must be invoked with at least 2 arguments.
+ - selector: ThrowStatement > CallExpression[callee.name=/Error$/]
+ message: Use new keyword when throwing an Error.
+ # Config specific to lib
+ - selector: NewExpression[callee.name=/Error$/]:not([callee.name=/^(AssertionError|NghttpError|AbortError)$/])
+ message: Use an error exported by the internal/errors module.
+ - selector: CallExpression[callee.object.name='Error'][callee.property.name='captureStackTrace']
+ message: Please use `require('internal/errors').hideStackFrames()` instead.
+ - selector: AssignmentExpression:matches([left.name='prepareStackTrace'], [left.property.name='prepareStackTrace'])
+ message: Use 'overrideStackTrace' from 'lib/internal/errors.js' instead of 'Error.prepareStackTrace'.
+ - selector: ThrowStatement > NewExpression[callee.name=/^ERR_[A-Z_]+$/] > ObjectExpression:first-child:not(:has([key.name='message']):has([key.name='code']):has([key.name='syscall']))
+ message: The context passed into SystemError constructor must have .code, .syscall and .message.
+ no-restricted-globals:
+ - error
+ - name: AbortController
+ message: Use `const { AbortController } = require('internal/abort_controller');` instead of the global.
+ - name: AbortSignal
+ message: Use `const { AbortSignal } = require('internal/abort_controller');` instead of the global.
+ # Atomics is not available in primordials because it can be
+ # disabled with --no-harmony-atomics CLI flag.
+ - name: Atomics
+ message: Use `const { Atomics } = globalThis;` instead of the global.
+ - name: Blob
+ message: Use `const { Blob } = require('buffer');` instead of the global.
+ - name: BroadcastChannel
+ message: Use `const { BroadcastChannel } = require('internal/worker/io');` instead of the global.
+ - name: Buffer
+ message: Use `const { Buffer } = require('buffer');` instead of the global.
+ - name: ByteLengthQueuingStrategy
+ message: Use `const { ByteLengthQueuingStrategy } = require('internal/webstreams/queuingstrategies')` instead of the global.
+ - name: CompressionStream
+ message: Use `const { CompressionStream } = require('internal/webstreams/compression')` instead of the global.
+ - name: CountQueuingStrategy
+ message: Use `const { CountQueuingStrategy } = require('internal/webstreams/queuingstrategies')` instead of the global.
+ - name: CustomEvent
+ message: Use `const { CustomEvent } = require('internal/event_target');` instead of the global.
+ - name: DecompressionStream
+ message: Use `const { DecompressionStream } = require('internal/webstreams/compression')` instead of the global.
+ - name: DOMException
+ message: Use lazy function `const { lazyDOMExceptionClass } = require('internal/util');` instead of the global.
+ - name: Event
+ message: Use `const { Event } = require('internal/event_target');` instead of the global.
+ - name: EventTarget
+ message: Use `const { EventTarget } = require('internal/event_target');` instead of the global.
+ - name: File
+ message: Use `const { File } = require('buffer');` instead of the global.
+ - name: FormData
+ message: Use `const { FormData } = require('internal/deps/undici/undici');` instead of the global.
+ - name: Headers
+ message: Use `const { Headers } = require('internal/deps/undici/undici');` instead of the global.
+ # Intl is not available in primordials because it can be
+ # disabled with --without-intl build flag.
+ - name: Intl
+ message: Use `const { Intl } = globalThis;` instead of the global.
+ - name: MessageChannel
+ message: Use `const { MessageChannel } = require('internal/worker/io');` instead of the global.
+ - name: MessageEvent
+ message: Use `const { MessageEvent } = require('internal/worker/io');` instead of the global.
+ - name: MessagePort
+ message: Use `const { MessagePort } = require('internal/worker/io');` instead of the global.
+ - name: PerformanceEntry
+ message: Use `const { PerformanceEntry } = require('perf_hooks');` instead of the global.
+ - name: PerformanceMark
+ message: Use `const { PerformanceMark } = require('perf_hooks');` instead of the global.
+ - name: PerformanceMeasure
+ message: Use `const { PerformanceMeasure } = require('perf_hooks');` instead of the global.
+ - name: PerformanceObserverEntryList
+ message: Use `const { PerformanceObserverEntryList } = require('perf_hooks');` instead of the global.
+ - name: PerformanceObserver
+ message: Use `const { PerformanceObserver } = require('perf_hooks');` instead of the global.
+ - name: PerformanceResourceTiming
+ message: Use `const { PerformanceResourceTiming } = require('perf_hooks');` instead of the global.
+ - name: ReadableStream
+ message: Use `const { ReadableStream } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: ReadableStreamDefaultReader
+ message: Use `const { ReadableStreamDefaultReader } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: ReadableStreamBYOBReader
+ message: Use `const { ReadableStreamBYOBReader } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: ReadableStreamBYOBRequest
+ message: Use `const { ReadableStreamBYOBRequest } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: ReadableByteStreamController
+ message: Use `const { ReadableByteStreamController } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: ReadableStreamDefaultController
+ message: Use `const { ReadableStreamDefaultController } = require('internal/webstreams/readablestream')` instead of the global.
+ - name: Request
+ message: Use `const { Request } = require('internal/deps/undici/undici');` instead of the global.
+ - name: Response
+ message: Use `const { Response } = require('internal/deps/undici/undici');` instead of the global.
+ # ShadowRealm is not available in primordials because it can be
+ # disabled with --no-harmony-shadow-realm CLI flag.
+ - name: ShadowRealm
+ message: Use `const { ShadowRealm } = globalThis;` instead of the global.
+ # SharedArrayBuffer is not available in primordials because it can be
+ # disabled with --no-harmony-sharedarraybuffer CLI flag.
+ - name: SharedArrayBuffer
+ message: Use `const { SharedArrayBuffer } = globalThis;` instead of the global.
+ - name: TextDecoder
+ message: Use `const { TextDecoder } = require('internal/encoding');` instead of the global.
+ - name: TextDecoderStream
+ message: Use `const { TextDecoderStream } = require('internal/webstreams/encoding')` instead of the global.
+ - name: TextEncoder
+ message: Use `const { TextEncoder } = require('internal/encoding');` instead of the global.
+ - name: TextEncoderStream
+ message: Use `const { TextEncoderStream } = require('internal/webstreams/encoding')` instead of the global.
+ - name: TransformStream
+ message: Use `const { TransformStream } = require('internal/webstreams/transformstream')` instead of the global.
+ - name: TransformStreamDefaultController
+ message: Use `const { TransformStreamDefaultController } = require('internal/webstreams/transformstream')` instead of the global.
+ - name: URL
+ message: Use `const { URL } = require('internal/url');` instead of the global.
+ - name: URLSearchParams
+ message: Use `const { URLSearchParams } = require('internal/url');` instead of the global.
+ # WebAssembly is not available in primordials because it can be
+ # disabled with --jitless CLI flag.
+ - name: WebAssembly
+ message: Use `const { WebAssembly } = globalThis;` instead of the global.
+ - name: WritableStream
+ message: Use `const { WritableStream } = require('internal/webstreams/writablestream')` instead of the global.
+ - name: WritableStreamDefaultWriter
+ message: Use `const { WritableStreamDefaultWriter } = require('internal/webstreams/writablestream')` instead of the global.
+ - name: WritableStreamDefaultController
+ message: Use `const { WritableStreamDefaultController } = require('internal/webstreams/writablestream')` instead of the global.
+ - name: atob
+ message: Use `const { atob } = require('buffer');` instead of the global.
+ - name: btoa
+ message: Use `const { btoa } = require('buffer');` instead of the global.
+ - name: clearImmediate
+ message: Use `const { clearImmediate } = require('timers');` instead of the global.
+ - name: clearInterval
+ message: Use `const { clearInterval } = require('timers');` instead of the global.
+ - name: clearTimeout
+ message: Use `const { clearTimeout } = require('timers');` instead of the global.
+ - name: console
+ message: Use `const console = require('internal/console/global');` instead of the global.
+ - name: crypto
+ message: Use `const { crypto } = require('internal/crypto/webcrypto');` instead of the global.
+ - name: Crypto
+ message: Use `const { Crypto } = require('internal/crypto/webcrypto');` instead of the global.
+ - name: CryptoKey
+ message: Use `const { CryptoKey } = require('internal/crypto/webcrypto');` instead of the global.
+ - name: fetch
+ message: Use `const { fetch } = require('internal/deps/undici/undici');` instead of the global.
+ - name: global
+ message: Use `const { globalThis } = primordials;` instead of `global`.
+ - name: globalThis
+ message: Use `const { globalThis } = primordials;` instead of the global.
+ - name: performance
+ message: Use `const { performance } = require('perf_hooks');` instead of the global.
+ - name: queueMicrotask
+ message: Use `const { queueMicrotask } = require('internal/process/task_queues');` instead of the global.
+ - name: setImmediate
+ message: Use `const { setImmediate } = require('timers');` instead of the global.
+ - name: setInterval
+ message: Use `const { setInterval } = require('timers');` instead of the global.
+ - name: setTimeout
+ message: Use `const { setTimeout } = require('timers');` instead of the global.
+ - name: structuredClone
+ message: Use `const { structuredClone } = require('internal/structured_clone');` instead of the global.
+ - name: SubtleCrypto
+ message: Use `const { SubtleCrypto } = require('internal/crypto/webcrypto');` instead of the global.
+ # Custom rules in tools/eslint-rules
+ node-core/avoid-prototype-pollution: error
+ node-core/lowercase-name-for-primitive: error
+ node-core/non-ascii-character: error
+ node-core/no-array-destructuring: error
+ node-core/prefer-primordials:
+ - error
+ - name: AggregateError
+ - name: Array
+ - name: ArrayBuffer
+ - name: BigInt
+ - name: BigInt64Array
+ - name: BigUint64Array
+ - name: Boolean
+ - name: DataView
+ - name: Date
+ - name: decodeURI
+ - name: decodeURIComponent
+ - name: encodeURI
+ - name: encodeURIComponent
+ - name: escape
+ - name: eval
+ - name: Error
+ ignore:
+ - prepareStackTrace
+ - stackTraceLimit
+ - name: EvalError
+ - name: FinalizationRegistry
+ into: Safe
+ - name: Float32Array
+ - name: Float64Array
+ - name: Function
+ - name: Int16Array
+ - name: Int32Array
+ - name: Int8Array
+ - name: isFinite
+ into: Number
+ - name: isNaN
+ into: Number
+ - name: JSON
+ - name: Map
+ into: Safe
+ - name: Math
+ - name: Number
+ - name: Object
+ - name: parseFloat
+ into: Number
+ - name: parseInt
+ into: Number
+ - name: Proxy
+ - name: Promise
+ - name: RangeError
+ - name: ReferenceError
+ - name: Reflect
+ - name: RegExp
+ - name: Set
+ into: Safe
+ - name: String
+ - name: Symbol
+ - name: SyntaxError
+ - name: TypeError
+ - name: Uint16Array
+ - name: Uint32Array
+ - name: Uint8Array
+ - name: Uint8ClampedArray
+ - name: unescape
+ - name: URIError
+ - name: WeakMap
+ into: Safe
+ - name: WeakRef
+ into: Safe
+ - name: WeakSet
+ into: Safe
+globals:
+ # Parameters passed to internal modules
+ require: false
+ process: false
+ exports: false
+ module: false
+ internalBinding: false
+ primordials: false
diff --git a/agents/otlp/src/datadog_metrics.cc b/agents/otlp/src/datadog_metrics.cc
new file mode 100644
index 00000000000..014606df570
--- /dev/null
+++ b/agents/otlp/src/datadog_metrics.cc
@@ -0,0 +1,153 @@
+#include "datadog_metrics.h"
+
+#include
+
+#include "asserts-cpp/asserts.h"
+
+using ProcessMetricsStor = node::nsolid::ProcessMetrics::MetricsStor;
+using ThreadMetricsStor = node::nsolid::ThreadMetrics::MetricsStor;
+using nlohmann::json;
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+static std::vector discarded_metrics = {
+ "thread_id", "timestamp"
+};
+
+const char* tid = "thread_id:";
+
+DatadogMetrics::DatadogMetrics(uv_loop_t* loop,
+ const std::string& url,
+ const std::string& key): loop_(loop),
+ key_(key),
+ url_(url) {
+ http_client_.reset(new OTLPHttpClient(loop_));
+}
+
+/*virtual*/
+DatadogMetrics::~DatadogMetrics() {
+}
+
+/*virtual*/
+void DatadogMetrics::got_proc_metrics(const ProcessMetricsStor& stor,
+ const ProcessMetricsStor& prev_stor) {
+ json series = json::array();
+
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ uint64_t ts = stor.timestamp / 1000; \
+ uint64_t prev_ts = prev_stor.timestamp / 1000; \
+ json m = { \
+ { "metric", "nsolid."#CName }, \
+ { "type", "count" }, \
+ { "interval", ts - prev_ts }, \
+ { "points", {{ ts, stor.CName - prev_stor.CName }}} \
+ }; \
+ series.push_back(m); \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ uint64_t ts = stor.timestamp / 1000; \
+ json m = { \
+ { "metric", "nsolid."#CName }, \
+ { "type", "gauge" }, \
+ { "points", {{ ts, stor.CName }}} \
+ }; \
+ series.push_back(m); \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_PROCESS_METRICS_NUMBERS(V)
+#undef V
+
+ json body = {
+ { "series", series }
+ };
+
+ http_client_->post_datadog_metrics(url_,
+ key_,
+ body.dump());
+}
+
+/*virtual*/
+void DatadogMetrics::got_thr_metrics(
+ const std::vector>& thr_metrics) {
+ json series = json::array();
+ for (const auto& tm : thr_metrics) {
+ got_thr_metrics(tm.first, tm.second, series);
+ }
+
+ if (series.size() > 0) {
+ json body = {
+ { "series", series }
+ };
+
+ http_client_->post_datadog_metrics(url_,
+ key_,
+ body.dump());
+ }
+}
+
+void DatadogMetrics::got_thr_metrics(const ThreadMetricsStor& stor,
+ const ThreadMetricsStor& prev_stor,
+ nlohmann::json& series) {
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ uint64_t ts = stor.timestamp / 1000; \
+ uint64_t prev_ts = prev_stor.timestamp / 1000; \
+ json m = { \
+ { "metric", "nsolid."#CName }, \
+ { "type", "count" }, \
+ { "interval", ts - prev_ts }, \
+ { "points", {{ ts, stor.CName - prev_stor.CName }}}, \
+ { "tags", { std::string(tid) + std::to_string(stor.thread_id) }} \
+ }; \
+ series.push_back(m); \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ uint64_t ts = stor.timestamp / 1000; \
+ json m = { \
+ { "metric", "nsolid."#CName }, \
+ { "type", "gauge" }, \
+ { "points", {{ ts, stor.CName }}}, \
+ { "tags", { std::string(tid) + std::to_string(stor.thread_id) }} \
+ }; \
+ series.push_back(m); \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_ENV_METRICS_NUMBERS(V)
+#undef V
+}
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
diff --git a/agents/otlp/src/datadog_metrics.h b/agents/otlp/src/datadog_metrics.h
new file mode 100644
index 00000000000..16fd3da17e9
--- /dev/null
+++ b/agents/otlp/src/datadog_metrics.h
@@ -0,0 +1,42 @@
+#ifndef AGENTS_OTLP_SRC_DATADOG_METRICS_H_
+#define AGENTS_OTLP_SRC_DATADOG_METRICS_H_
+
+#include "metrics_exporter.h"
+#include "http_client.h"
+#include "nlohmann/json.h"
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+class DatadogMetrics final: public MetricsExporter {
+ public:
+ DatadogMetrics(uv_loop_t* loop,
+ const std::string& url,
+ const std::string& key);
+ virtual ~DatadogMetrics();
+
+ virtual void got_proc_metrics(const ProcessMetrics::MetricsStor& stor,
+ const ProcessMetrics::MetricsStor& prev_stor);
+
+ void got_thr_metrics(
+ const std::vector>&);
+
+ private:
+ void got_thr_metrics(const ThreadMetrics::MetricsStor& stor,
+ const ThreadMetrics::MetricsStor& prev_stor,
+ nlohmann::json& series); // NOLINT(runtime/references)
+
+ uv_loop_t* loop_;
+ std::unique_ptr http_client_;
+ std::string key_;
+ std::string url_;
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_OTLP_SRC_DATADOG_METRICS_H_
diff --git a/agents/otlp/src/dynatrace_metrics.cc b/agents/otlp/src/dynatrace_metrics.cc
new file mode 100644
index 00000000000..03c7a163361
--- /dev/null
+++ b/agents/otlp/src/dynatrace_metrics.cc
@@ -0,0 +1,128 @@
+#include "dynatrace_metrics.h"
+
+#include
+
+#include "asserts-cpp/asserts.h"
+
+using ProcessMetricsStor = node::nsolid::ProcessMetrics::MetricsStor;
+using ThreadMetricsStor = node::nsolid::ThreadMetrics::MetricsStor;
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+static std::vector discarded_metrics = {
+ "thread_id", "timestamp"
+};
+
+DynatraceMetrics::DynatraceMetrics(uv_loop_t* loop,
+ const std::string& endpoint,
+ const std::string& auth_header):
+ loop_(loop),
+ auth_header_(auth_header),
+ endpoint_(endpoint + "/api/v2/metrics/ingest") {
+ http_client_.reset(new OTLPHttpClient(loop_));
+}
+
+/*virtual*/
+DynatraceMetrics::~DynatraceMetrics() {
+}
+
+/*virtual*/
+void DynatraceMetrics::got_proc_metrics(const ProcessMetricsStor& stor,
+ const ProcessMetricsStor& prev_stor) {
+ std::string metrics;
+
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ metrics += "nsolid."#CName; \
+ metrics += " count,delta="; \
+ metrics += std::to_string(stor.CName - prev_stor.CName); \
+ metrics += "\n"; \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ metrics += "nsolid."#CName; \
+ metrics += " gauge,"; \
+ metrics += std::to_string(stor.CName); \
+ metrics += "\n"; \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_PROCESS_METRICS_NUMBERS(V)
+#undef V
+
+ http_client_->post_dynatrace_metrics(endpoint_,
+ auth_header_,
+ metrics);
+}
+
+/*virtual*/
+void DynatraceMetrics::got_thr_metrics(
+ const std::vector>& thr_metrics) {
+ std::string metrics;
+ for (const auto& tm : thr_metrics) {
+ metrics += got_thr_metrics(tm.first, tm.second);
+ }
+
+ if (metrics.size() > 0) {
+ http_client_->post_dynatrace_metrics(endpoint_,
+ auth_header_,
+ metrics);
+ }
+}
+
+std::string DynatraceMetrics::got_thr_metrics(
+ const ThreadMetricsStor& stor,
+ const ThreadMetricsStor& prev_stor) {
+ std::string metrics;
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ metrics += "nsolid."#CName; \
+ metrics += ",thread_id=" + std::to_string(stor.thread_id); \
+ metrics += " count,delta="; \
+ metrics += std::to_string(stor.CName - prev_stor.CName); \
+ metrics += "\n"; \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ metrics += "nsolid."#CName; \
+ metrics += " gauge,"; \
+ metrics += std::to_string(stor.CName); \
+ metrics += "\n"; \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_ENV_METRICS_NUMBERS(V)
+#undef V
+ return metrics;
+}
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
diff --git a/agents/otlp/src/dynatrace_metrics.h b/agents/otlp/src/dynatrace_metrics.h
new file mode 100644
index 00000000000..6d263941f06
--- /dev/null
+++ b/agents/otlp/src/dynatrace_metrics.h
@@ -0,0 +1,41 @@
+#ifndef AGENTS_OTLP_SRC_DYNATRACE_METRICS_H_
+#define AGENTS_OTLP_SRC_DYNATRACE_METRICS_H_
+
+#include "metrics_exporter.h"
+#include "http_client.h"
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+class DynatraceMetrics final: public MetricsExporter {
+ public:
+ DynatraceMetrics(uv_loop_t* loop,
+ const std::string& endpoint,
+ const std::string& auth_header);
+ virtual ~DynatraceMetrics();
+
+ virtual void got_proc_metrics(const ProcessMetrics::MetricsStor& stor,
+ const ProcessMetrics::MetricsStor& prev_stor);
+
+ void got_thr_metrics(
+ const std::vector>&);
+
+
+ private:
+ std::string got_thr_metrics(const ThreadMetrics::MetricsStor& stor,
+ const ThreadMetrics::MetricsStor& prev_stor);
+
+ uv_loop_t* loop_;
+ std::unique_ptr http_client_;
+ std::string auth_header_;
+ std::string endpoint_;
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_OTLP_SRC_DYNATRACE_METRICS_H_
diff --git a/agents/otlp/src/http_client.cc b/agents/otlp/src/http_client.cc
new file mode 100644
index 00000000000..42e7c7dac09
--- /dev/null
+++ b/agents/otlp/src/http_client.cc
@@ -0,0 +1,86 @@
+#include "http_client.h"
+#include "debug_utils-inl.h"
+#include "asserts-cpp/asserts.h"
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+template
+inline void Debug(Args&&... args) {
+ per_process::Debug(DebugCategory::NSOLID_OTLP_AGENT,
+ std::forward(args)...);
+}
+
+OTLPHttpClient::OTLPHttpClient(uv_loop_t* loop): HttpClient(loop) {
+}
+
+int OTLPHttpClient::post_datadog_metrics(const std::string& url,
+ const std::string& key,
+ const std::string& metrics) {
+ static std::string auth = "DD-API-KEY: ";
+ struct curl_slist* header_list = nullptr;
+ header_list = curl_slist_append(header_list, std::string(auth + key).c_str());
+ header_list = curl_slist_append(header_list, "Content-Type: text/json");
+ return post_metrics(url, metrics, header_list);
+}
+
+int OTLPHttpClient::post_dynatrace_metrics(const std::string& url,
+ const std::string& auth_header,
+ const std::string& metrics) {
+ static std::string auth = "Authorization: ";
+ struct curl_slist* header_list = nullptr;
+ header_list = curl_slist_append(header_list,
+ std::string(auth + auth_header).c_str());
+ header_list = curl_slist_append(header_list, "Content-Type: text/plain");
+ return post_metrics(url, metrics, header_list);
+}
+
+int OTLPHttpClient::post_newrelic_metrics(const std::string& url,
+ const std::string& key,
+ const std::string& metrics) {
+ static std::string auth = "api-key: ";
+ struct curl_slist* header_list = nullptr;
+ header_list = curl_slist_append(header_list, std::string(auth + key).c_str());
+ header_list = curl_slist_append(header_list,
+ "Content-Type: application/json");
+ return post_metrics(url, metrics, header_list);
+}
+
+int OTLPHttpClient::post_metrics(const std::string& url,
+ const std::string& metrics,
+ struct curl_slist* header_list) {
+ Debug("Posting Metrics to '%s'\n", url.c_str());
+ CURL* handle = curl_easy_init();
+ ASSERT_NOT_NULL(handle);
+
+ auto stor = new HttpClientStor{ this, header_list };
+
+ ASSERT_EQ(0, curl_easy_setopt(handle, CURLOPT_PRIVATE, stor));
+ ASSERT_EQ(0, curl_easy_setopt(handle, CURLOPT_URL, url.c_str()));
+ ASSERT_EQ(0, curl_easy_setopt(handle, CURLOPT_POST, 1L));
+ ASSERT_EQ(0, curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header_list));
+ ASSERT_EQ(0, curl_easy_setopt(handle,
+ CURLOPT_COPYPOSTFIELDS,
+ metrics.c_str()));
+ ASSERT_EQ(0, curl_easy_setopt(handle,
+ CURLOPT_WRITEFUNCTION,
+ HttpClient::write_cb_));
+ struct curl_blob blob;
+ blob.data = const_cast(cacert_.c_str());
+ blob.len = cacert_.size();
+ blob.flags = CURL_BLOB_NOCOPY;
+ ASSERT_EQ(0, curl_easy_setopt(handle, CURLOPT_CAINFO_BLOB, &blob));
+ ASSERT_EQ(0, curl_multi_add_handle(curl_handle_, handle));
+ return 0;
+}
+
+/*virtual*/void OTLPHttpClient::transfer_done(CURLMsg* message,
+ struct HttpClientStor* stor) {
+ auto header_list = reinterpret_cast(stor->data);
+ curl_slist_free_all(header_list);
+}
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
diff --git a/agents/otlp/src/http_client.h b/agents/otlp/src/http_client.h
new file mode 100644
index 00000000000..fc2f96d731a
--- /dev/null
+++ b/agents/otlp/src/http_client.h
@@ -0,0 +1,38 @@
+#ifndef AGENTS_OTLP_SRC_HTTP_CLIENT_H_
+#define AGENTS_OTLP_SRC_HTTP_CLIENT_H_
+
+#include "../../src/http_client.h"
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+class OTLPHttpClient: public HttpClient {
+ public:
+ explicit OTLPHttpClient(uv_loop_t* loop);
+ ~OTLPHttpClient() {}
+
+ int post_datadog_metrics(const std::string& url,
+ const std::string& key,
+ const std::string& metrics);
+ int post_dynatrace_metrics(const std::string& url,
+ const std::string& auth_header,
+ const std::string& metrics);
+ int post_newrelic_metrics(const std::string& url,
+ const std::string& key,
+ const std::string& metrics);
+
+ virtual void transfer_done(CURLMsg* message, struct HttpClientStor* stor);
+
+ private:
+ int post_metrics(const std::string& url,
+ const std::string& metrics,
+ struct curl_slist* header_list);
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_OTLP_SRC_HTTP_CLIENT_H_
diff --git a/agents/otlp/src/metrics_exporter.h b/agents/otlp/src/metrics_exporter.h
new file mode 100644
index 00000000000..dbec98d8a7a
--- /dev/null
+++ b/agents/otlp/src/metrics_exporter.h
@@ -0,0 +1,30 @@
+#ifndef AGENTS_OTLP_SRC_METRICS_EXPORTER_H_
+#define AGENTS_OTLP_SRC_METRICS_EXPORTER_H_
+
+#include
+#include
+#include
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+class MetricsExporter {
+ public:
+ virtual ~MetricsExporter() {}
+
+ virtual void got_proc_metrics(
+ const ProcessMetrics::MetricsStor& stor,
+ const ProcessMetrics::MetricsStor& prev_stor) = 0;
+
+ virtual void got_thr_metrics(
+ const std::vector>&) = 0;
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_OTLP_SRC_METRICS_EXPORTER_H_
diff --git a/agents/otlp/src/newrelic_metrics.cc b/agents/otlp/src/newrelic_metrics.cc
new file mode 100644
index 00000000000..87f076a8fc7
--- /dev/null
+++ b/agents/otlp/src/newrelic_metrics.cc
@@ -0,0 +1,162 @@
+#include "newrelic_metrics.h"
+
+#include
+
+#include "asserts-cpp/asserts.h"
+
+using ProcessMetricsStor = node::nsolid::ProcessMetrics::MetricsStor;
+using ThreadMetricsStor = node::nsolid::ThreadMetrics::MetricsStor;
+using nlohmann::json;
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+static std::vector discarded_metrics = {
+ "thread_id", "timestamp"
+};
+
+NewRelicMetrics::NewRelicMetrics(uv_loop_t* loop,
+ const std::string& url,
+ const std::string& key)
+ : loop_(loop),
+ key_(key),
+ url_(url) {
+ http_client_.reset(new OTLPHttpClient(loop_));
+}
+
+/*virtual*/
+NewRelicMetrics::~NewRelicMetrics() {
+}
+
+/*virtual*/
+void NewRelicMetrics::got_proc_metrics(
+ const ProcessMetricsStor& stor,
+ const ProcessMetricsStor& prev_stor) {
+ json metrics = json::array();
+
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ json m = { \
+ { "name", "nsolid."#CName }, \
+ { "type", "count" }, \
+ { "value", stor.CName - prev_stor.CName } \
+ }; \
+ metrics.push_back(m); \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ json m = { \
+ { "name", "nsolid."#CName }, \
+ { "type", "gauge" }, \
+ { "value", stor.CName } \
+ }; \
+ metrics.push_back(m); \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_PROCESS_METRICS_NUMBERS(V)
+#undef V
+
+ json body = json::array();
+ json common = {
+ { "timestamp", stor.timestamp },
+ { "interval.ms", stor.timestamp - prev_stor.timestamp }
+ };
+
+ body.push_back({
+ { "common", common },
+ { "metrics", metrics }
+ });
+
+ http_client_->post_newrelic_metrics(url_,
+ key_,
+ body.dump());
+}
+
+/*virtual*/
+void NewRelicMetrics::got_thr_metrics(
+ const std::vector>& thr_metrics) {
+ json body = json::array();
+ for (const auto& tm : thr_metrics) {
+ body.push_back(got_thr_metrics(tm.first, tm.second));
+ }
+
+ if (body.size() > 0) {
+ http_client_->post_newrelic_metrics(url_,
+ key_,
+ body.dump());
+ }
+}
+
+json NewRelicMetrics::got_thr_metrics(const ThreadMetricsStor& stor,
+ const ThreadMetricsStor& prev_stor) {
+ json metrics = json::array();
+#define V(CType, CName, JSName, MType) \
+{ \
+ auto it = std::find(discarded_metrics.begin(), \
+ discarded_metrics.end(), \
+ #CName); \
+ if (it == discarded_metrics.end()) { \
+ switch (MetricsType::MType) { \
+ case MetricsType::ECounter: \
+ { \
+ json m = { \
+ { "name", "nsolid."#CName }, \
+ { "type", "count" }, \
+ { "value", stor.CName - prev_stor.CName } \
+ }; \
+ metrics.push_back(m); \
+ } \
+ break; \
+ case MetricsType::EGauge: \
+ { \
+ json m = { \
+ { "name", "nsolid."#CName }, \
+ { "type", "gauge" }, \
+ { "value", stor.CName } \
+ }; \
+ metrics.push_back(m); \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+ } \
+}
+ NSOLID_ENV_METRICS_NUMBERS(V)
+#undef V
+
+ json common = {
+ { "timestamp", stor.timestamp },
+ { "interval.ms", stor.timestamp - prev_stor.timestamp },
+ { "attributes", {
+ { "thread_id", stor.thread_id },
+ { "thread_name", stor.thread_name }
+ }}
+ };
+
+ json thr_metrics = {
+ { "common", common },
+ { "metrics", metrics }
+ };
+
+ return thr_metrics;
+}
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
diff --git a/agents/otlp/src/newrelic_metrics.h b/agents/otlp/src/newrelic_metrics.h
new file mode 100644
index 00000000000..98a1361d7fb
--- /dev/null
+++ b/agents/otlp/src/newrelic_metrics.h
@@ -0,0 +1,41 @@
+#ifndef AGENTS_OTLP_SRC_NEWRELIC_METRICS_H_
+#define AGENTS_OTLP_SRC_NEWRELIC_METRICS_H_
+
+#include "metrics_exporter.h"
+#include "http_client.h"
+#include "nlohmann/json.h"
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+class NewRelicMetrics final: public MetricsExporter {
+ public:
+ NewRelicMetrics(uv_loop_t* loop,
+ const std::string& url,
+ const std::string& key);
+ virtual ~NewRelicMetrics();
+
+ virtual void got_proc_metrics(const ProcessMetrics::MetricsStor& stor,
+ const ProcessMetrics::MetricsStor& prev_stor);
+
+ void got_thr_metrics(
+ const std::vector>&);
+
+ private:
+ nlohmann::json got_thr_metrics(const ThreadMetrics::MetricsStor& stor,
+ const ThreadMetrics::MetricsStor& prev_stor);
+
+ uv_loop_t* loop_;
+ std::unique_ptr http_client_;
+ std::string key_;
+ std::string url_;
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_OTLP_SRC_NEWRELIC_METRICS_H_
diff --git a/agents/otlp/src/otlp_agent.cc b/agents/otlp/src/otlp_agent.cc
new file mode 100644
index 00000000000..c43385cb850
--- /dev/null
+++ b/agents/otlp/src/otlp_agent.cc
@@ -0,0 +1,625 @@
+#include "otlp_agent.h"
+#include "debug_utils-inl.h"
+#include "datadog_metrics.h"
+#include "dynatrace_metrics.h"
+#include "newrelic_metrics.h"
+#include "opentelemetry/sdk/resource/resource.h"
+#include "opentelemetry/sdk/trace/recordable.h"
+#include "opentelemetry/exporters/otlp/otlp_http_exporter.h"
+#include "opentelemetry/trace/propagation/detail/hex.h"
+
+using ThreadMetricsStor = node::nsolid::ThreadMetrics::MetricsStor;
+using nlohmann::json;
+
+namespace nostd = OPENTELEMETRY_NAMESPACE::nostd;
+namespace sdk = OPENTELEMETRY_NAMESPACE::sdk;
+namespace exporter = OPENTELEMETRY_NAMESPACE::exporter;
+namespace trace = OPENTELEMETRY_NAMESPACE::trace;
+namespace resource = sdk::resource;
+namespace detail = trace::propagation::detail;
+
+static const size_t kTraceIdSize = 32;
+static const size_t kSpanIdSize = 16;
+
+static std::atomic is_running_ = { false };
+static resource::ResourceAttributes resource_attributes_;
+
+namespace node {
+namespace nsolid {
+namespace otlp {
+
+template
+inline void Debug(Args&&... args) {
+ per_process::Debug(DebugCategory::NSOLID_OTLP_AGENT,
+ std::forward(args)...);
+}
+
+inline void DebugJSON(const char* str, const json& msg) {
+ if (UNLIKELY(per_process::enabled_debug_list.enabled(
+ DebugCategory::NSOLID_OTLP_AGENT))) {
+ Debug(str, msg.dump(4).c_str());
+ }
+}
+
+
+OTLPAgent* OTLPAgent::Inst() {
+ static OTLPAgent agent;
+ return &agent;
+}
+
+
+OTLPAgent::OTLPAgent(): ready_(false),
+ hooks_init_(false),
+ trace_flags_(0),
+ otlp_http_exporter_(nullptr),
+ metrics_interval_(0),
+ proc_metrics_(),
+ proc_prev_stor_(),
+ config_(json::object()) {
+ ASSERT_EQ(0, uv_loop_init(&loop_));
+ ASSERT_EQ(0, uv_cond_init(&start_cond_));
+ ASSERT_EQ(0, uv_mutex_init(&start_lock_));
+ ASSERT_EQ(0, exit_lock_.init(true));
+ is_running_ = true;
+}
+
+
+OTLPAgent::~OTLPAgent() {
+ {
+ nsuv::ns_rwlock::scoped_wrlock lock(exit_lock_);
+ is_running_ = false;
+ }
+ ASSERT_EQ(0, stop());
+ uv_mutex_destroy(&start_lock_);
+ uv_cond_destroy(&start_cond_);
+ ASSERT_EQ(0, uv_loop_close(&loop_));
+}
+
+
+int OTLPAgent::start() {
+ int r = 0;
+ if (ready_ == false) {
+ uv_mutex_lock(&start_lock_);
+ r = thread_.create(run_, this);
+ if (r == 0) {
+ while (ready_ == false) {
+ uv_cond_wait(&start_cond_, &start_lock_);
+ }
+ }
+
+ uv_mutex_unlock(&start_lock_);
+ }
+
+ return r;
+}
+
+
+int OTLPAgent::stop() {
+ int r = 0;
+ if (ready_ == true) {
+ r = shutdown_.send();
+ if (r != 0) {
+ return r;
+ }
+
+ r = thread_.join();
+ if (r != 0) {
+ return r;
+ }
+ }
+
+ return r;
+}
+
+using string_vector = std::vector;
+static string_vector apm_fields({ "/datadog",
+ "/dynatrace",
+ "/newrelic",
+ "/otlp" });
+
+static string_vector metrics_fields({ "/interval",
+ "/pauseMetrics" });
+
+static string_vector otlp_fields({ "/otlp",
+ "/otlpConfig" });
+
+static string_vector tracing_fields({ "/tracingEnabled",
+ "/tracingModulesBlacklist" });
+
+
+int OTLPAgent::config(const nlohmann::json& config) {
+ json diff = json::diff(config_, config);
+ DebugJSON("Old Config: \n%s\n", config_);
+ DebugJSON("NewConfig: \n%s\n", config);
+ DebugJSON("Diff: \n%s\n", diff);
+ config_ = config;
+ if (utils::find_any_fields_in_diff(diff, otlp_fields)) {
+ config_otlp_agent(config_);
+ }
+
+ // Configure tracing flags
+ if (trace_flags_ == 0 ||
+ utils::find_any_fields_in_diff(diff, tracing_fields)) {
+ trace_flags_ = 0;
+ if (otlp_http_exporter_ != nullptr) {
+ auto it = config_.find("tracingEnabled");
+ if (it != config_.end()) {
+ bool tracing_enabled = *it;
+ if (tracing_enabled) {
+ trace_flags_ = Tracer::kSpanDns |
+ Tracer::kSpanHttpClient |
+ Tracer::kSpanHttpServer |
+ Tracer::kSpanCustom;
+ it = config_.find("tracingModulesBlacklist");
+ if (it != config_.end()) {
+ const uint32_t blacklisted = *it;
+ trace_flags_ &= ~blacklisted;
+ }
+ }
+ }
+ }
+
+ update_tracer(trace_flags_);
+ }
+
+ // If metrics timer is not active or if the diff contains metrics fields,
+ // recalculate the metrics status. (stop/start/what period)
+ if (!metrics_timer_.is_active() ||
+ utils::find_any_fields_in_diff(diff, metrics_fields)) {
+ uint64_t period = 0;
+ if (metrics_exporter_ != nullptr) {
+ auto it = config_.find("pauseMetrics");
+ if (it != config_.end()) {
+ bool pause = *it;
+ if (!pause) {
+ it = config_.find("interval");
+ if (it != config_.end()) {
+ period = *it;
+ }
+ }
+ }
+ }
+
+ metrics_interval_ = period;
+ return setup_metrics_timer(metrics_interval_);
+ }
+
+ return 0;
+}
+
+
+/*static*/ void OTLPAgent::run_(nsuv::ns_thread*, OTLPAgent* agent) {
+ agent->do_start();
+ do {
+ ASSERT_EQ(0, uv_run(&agent->loop_, UV_RUN_DEFAULT));
+ } while (uv_loop_alive(&agent->loop_));
+}
+
+/*static*/ void OTLPAgent::shutdown_cb_(nsuv::ns_async*, OTLPAgent* agent) {
+ agent->do_stop();
+}
+
+
+/*static*/ void OTLPAgent::config_agent_cb_(std::string config,
+ OTLPAgent* agent) {
+ // Check if the agent is already delete or if it's closing
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ json cfg = json::parse(config, nullptr, false);
+ // assert because the runtime should never send me an invalid JSON config
+ ASSERT(!cfg.is_discarded());
+ agent->config_msg_q_.enqueue(cfg);
+ ASSERT_EQ(0, agent->config_msg_.send());
+}
+
+
+/*static*/ void OTLPAgent::config_msg_cb_(nsuv::ns_async*, OTLPAgent* agent) {
+ json config_msg;
+ while (agent->config_msg_q_.dequeue(config_msg)) {
+ agent->config(config_msg);
+ }
+}
+
+
+/*static*/ void OTLPAgent::env_msg_cb_(nsuv::ns_async*, OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ std::tuple tup;
+ while (agent->env_msg_q_.dequeue(tup)) {
+ SharedEnvInst envinst = std::get<0>(tup);
+ bool creation = std::get<1>(tup);
+ if (creation) {
+ auto pair = agent->env_metrics_map_.emplace(
+ std::piecewise_construct,
+ std::forward_as_tuple(GetThreadId(envinst)),
+ std::forward_as_tuple(envinst));
+ ASSERT(pair.second);
+ } else {
+ ASSERT_EQ(1, agent->env_metrics_map_.erase(GetThreadId(envinst)));
+ }
+ }
+}
+
+
+/*static*/ void OTLPAgent::on_thread_add_(SharedEnvInst envinst,
+ OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ agent->env_msg_q_.enqueue({ envinst, true });
+ ASSERT_EQ(0, agent->env_msg_.send());
+}
+
+
+/*static*/ void OTLPAgent::on_thread_remove_(SharedEnvInst envinst,
+ OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ agent->env_msg_q_.enqueue({ envinst, false });
+ ASSERT_EQ(0, agent->env_msg_.send());
+}
+
+
+void OTLPAgent::do_start() {
+ uv_mutex_lock(&start_lock_);
+ ASSERT_EQ(0, shutdown_.init(&loop_, shutdown_cb_, this));
+ ASSERT_EQ(0, env_msg_.init(&loop_, env_msg_cb_, this));
+ ASSERT_EQ(0, span_msg_.init(&loop_, span_msg_cb_, this));
+ ASSERT_EQ(0, metrics_msg_.init(&loop_, metrics_msg_cb_, this));
+ ASSERT_EQ(0, metrics_timer_.init(&loop_));
+ ASSERT_EQ(0, config_msg_.init(&loop_, config_msg_cb_, this));
+
+ if (!hooks_init_) {
+ ASSERT_EQ(0, OnConfigurationHook(config_agent_cb_, this));
+ ASSERT_EQ(0, ThreadAddedHook(on_thread_add_, this));
+ ASSERT_EQ(0, ThreadRemovedHook(on_thread_remove_, this));
+ hooks_init_ = true;
+ }
+
+ ready_ = true;
+
+ uv_cond_signal(&start_cond_);
+ uv_mutex_unlock(&start_lock_);
+}
+
+
+void OTLPAgent::do_stop() {
+ shutdown_.close();
+ env_msg_.close();
+ span_msg_.close();
+ metrics_msg_.close();
+ metrics_timer_.close();
+ config_msg_.close();
+ metrics_exporter_.reset(nullptr);
+ ready_ = false;
+}
+
+
+void OTLPAgent::trace_hook_(Tracer* tracer,
+ const Tracer::SpanStor& stor,
+ OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ agent->span_msg_q_.enqueue(stor);
+ ASSERT_EQ(0, agent->span_msg_.send());
+}
+
+
+void OTLPAgent::span_msg_cb_(nsuv::ns_async*, OTLPAgent* agent) {
+ // Don't exit until all the pending spans are sent
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ using std::chrono::duration_cast;
+ using time_point = std::chrono::system_clock::time_point;
+ using std::chrono::milliseconds;
+ using std::chrono::nanoseconds;
+ auto resource = resource::Resource::Create(resource_attributes_);
+ std::vector> recordables;
+ Tracer::SpanStor s;
+ while (agent->span_msg_q_.dequeue(s)) {
+ auto recordable = agent->otlp_http_exporter_->MakeRecordable();
+ recordable->SetName(s.name);
+ time_point start{
+ duration_cast(
+ milliseconds(static_cast(s.start)))};
+ recordable->SetStartTime(start);
+ recordable->SetDuration(
+ nanoseconds(static_cast((s.end - s.start) * 1e6)));
+
+ uint8_t span_buf[kSpanIdSize / 2];
+ detail::HexToBinary(s.span_id, span_buf, sizeof(span_buf));
+
+ uint8_t parent_buf[kSpanIdSize / 2];
+ detail::HexToBinary(s.parent_id, parent_buf, sizeof(parent_buf));
+
+ uint8_t trace_buf[kTraceIdSize / 2];
+ detail::HexToBinary(s.trace_id, trace_buf, sizeof(trace_buf));
+
+ trace::SpanContext ctx(trace::TraceId(trace_buf),
+ trace::SpanId(span_buf),
+ trace::TraceFlags(0),
+ false);
+
+ trace::SpanId parent_id(parent_buf);
+
+ recordable->SetIdentity(ctx, parent_id);
+
+ recordable->SetSpanKind(static_cast(s.kind));
+
+ json attrs = json::parse(s.attrs);
+ ASSERT(!attrs.is_discarded());
+ for (const auto& attr : attrs.items()) {
+ const json val = attr.value();
+ if (val.is_boolean())
+ recordable->SetAttribute(attr.key(), attr.value().get());
+ else if (val.is_number_integer())
+ recordable->SetAttribute(attr.key(), attr.value().get());
+ else if (val.is_number_unsigned())
+ recordable->SetAttribute(attr.key(), attr.value().get());
+ else if (val.is_number_float())
+ recordable->SetAttribute(attr.key(), attr.value().get());
+ else if (val.is_string())
+ recordable->SetAttribute(attr.key(), attr.value().get());
+ }
+
+ recordable->SetAttribute("thread.id", s.thread_id);
+
+ recordable->SetResource(resource);
+
+ recordables.push_back(std::move(recordable));
+ }
+
+ nostd::span> batch(recordables);
+ auto result = agent->otlp_http_exporter_->Export(batch);
+ Debug("# Spans Exported: %ld. Result: %d\n",
+ recordables.size(),
+ static_cast(result));
+ // ASSERT_EQ(sdk::common::ExportResult::kSuccess, result);
+}
+
+
+/*static*/void OTLPAgent::metrics_timer_cb_(nsuv::ns_timer*, OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ agent->got_proc_metrics();
+ for (auto& item : agent->env_metrics_map_) {
+ int r = item.second.metrics_.Update(thr_metrics_cb_, agent);
+ // The UV_ESRCH and UV_EBADF errors can happen during the env shutdown
+ // process. Leaving this assertion for the moment in case another error is
+ // returned at some point.
+ // TODO(santi): Remove the assertion
+ ASSERT(r == 0 || r == UV_ESRCH || r == UV_EBADF);
+ }
+}
+
+
+/*static*/void OTLPAgent::metrics_msg_cb_(nsuv::ns_async*, OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ std::vector> thr_metrics_vector;
+ ThreadMetrics* m;
+ while (agent->thr_metrics_msg_q_.dequeue(&m)) {
+ auto it = agent->env_metrics_map_.find(m->thread_id());
+ if (it != agent->env_metrics_map_.end()) {
+ auto& metrics = it->second;
+ ThreadMetricsStor stor = m->Get();
+ thr_metrics_vector.emplace_back(stor, metrics.prev_);
+ metrics.prev_ = stor;
+ }
+ }
+
+ if (agent->metrics_exporter_) {
+ agent->metrics_exporter_->got_thr_metrics(thr_metrics_vector);
+ }
+}
+
+
+/*static*/void OTLPAgent::thr_metrics_cb_(ThreadMetrics* metrics,
+ OTLPAgent* agent) {
+ nsuv::ns_rwlock::scoped_rdlock lock(agent->exit_lock_);
+ if (!is_running_) {
+ return;
+ }
+
+ agent->thr_metrics_msg_q_.enqueue(metrics);
+ ASSERT_EQ(0, uv_async_send(&agent->metrics_msg_));
+}
+
+
+void OTLPAgent::config_datadog(const json& config) {
+ std::string url;
+ std::string metrics_url;
+ auto it = config.find("zone");
+ ASSERT(it != config.end());
+ std::string zone = *it;
+ if (zone == "eu") {
+ metrics_url += "https://api.datadoghq.eu/api/v1/series";
+ } else { // zone == "us"
+ metrics_url += "https://api.datadoghq.com/api/v1/series";
+ }
+
+ it = config.find("key");
+ ASSERT(it != config.end());
+ std::string key = *it;
+ exporter::otlp::OtlpHttpExporterOptions opts;
+ it = config.find("url");
+ ASSERT(it != config.end());
+ opts.url = it->get() + "/v1/traces";
+ setup_trace_otlp_exporter(opts);
+ metrics_exporter_.reset(new DatadogMetrics(&loop_, metrics_url, key));
+}
+
+
+void OTLPAgent::config_dynatrace(const json& config) {
+ auto it = config.find("site");
+ ASSERT(it != config.end());
+ std::string url = std::string("https://") +
+ it->get() +
+ std::string(".live.dynatrace.com");
+ it = config.find("token");
+ ASSERT(it != config.end());
+ std::string auth_header = std::string("Api-Token ") + it->get();
+ exporter::otlp::OtlpHttpExporterOptions opts;
+ opts.url = url + "/api/v2/otlp/v1/traces";
+ opts.http_headers.insert(std::make_pair("Authorization",
+ auth_header.c_str()));
+ setup_trace_otlp_exporter(opts);
+ metrics_exporter_.reset(new DynatraceMetrics(&loop_, url, auth_header));
+}
+
+
+void OTLPAgent::config_endpoint(const std::string& type,
+ const json& config) {
+ if (type == "datadog") {
+ config_datadog(config);
+ return;
+ }
+
+ if (type == "dynatrace") {
+ config_dynatrace(config);
+ return;
+ }
+
+ if (type == "newrelic") {
+ config_newrelic(config);
+ return;
+ }
+
+ if (type == "otlp") {
+ config_otlp_endpoint(config);
+ return;
+ }
+}
+
+
+void OTLPAgent::config_newrelic(const json& config) {
+ std::string url;
+ std::string metrics_url;
+ auto it = config.find("zone");
+ ASSERT(it != config.end());
+ std::string zone = *it;
+ if (zone == "eu") {
+ url += "https://otlp.eu01.nr-data.net:4318";
+ metrics_url += "https://metric-api.eu.newrelic.com/metric/v1";
+ } else { // zone == "us"
+ url += "https://otlp.nr-data.net:4318";
+ metrics_url += "https://metric-api.newrelic.com/metric/v1";
+ }
+
+ it = config.find("key");
+ ASSERT(it != config.end());
+ std::string key = *it;
+ exporter::otlp::OtlpHttpExporterOptions opts;
+ opts.url = url + "/v1/traces";
+ opts.http_headers.insert(std::make_pair("api-key", key.c_str()));
+ setup_trace_otlp_exporter(opts);
+ metrics_exporter_.reset(new NewRelicMetrics(&loop_, metrics_url, key));
+}
+
+
+void OTLPAgent::config_otlp_agent(const json& config) {
+ auto it = config.find("otlp");
+ if (it != config.end()) {
+ // Reset the otlp and metrics exporters and reconfigure endpoints.
+ otlp_http_exporter_.reset(nullptr);
+ metrics_exporter_.reset(nullptr);
+ std::string type = *it;
+ it = config.find("otlpConfig");
+ ASSERT(it != config.end());
+ const nlohmann::json& otlp = it.value();
+ config_endpoint(type, otlp);
+ config_service(config);
+ } else {
+ Debug("No otlp agent configuration. Stopping the agent\n");
+ stop();
+ }
+}
+
+
+void OTLPAgent::config_otlp_endpoint(const json& config) {
+ auto it = config.find("url");
+ ASSERT(it != config.end());
+ exporter::otlp::OtlpHttpExporterOptions opts;
+ opts.url = it->get() + "/v1/traces";
+ setup_trace_otlp_exporter(opts);
+}
+
+
+void OTLPAgent::config_service(const json& config) {
+ auto it = config.find("app");
+ ASSERT(it != config.end());
+ resource_attributes_.SetAttribute("service.name", it->get());
+ resource_attributes_.SetAttribute("service.version", "1.0.0");
+ it = config.find("appVersion");
+ if (it != config.end()) {
+ resource_attributes_.SetAttribute("service.version",
+ it->get());
+ }
+}
+
+
+void OTLPAgent::got_proc_metrics() {
+ ASSERT_EQ(0, proc_metrics_.Update());
+ ProcessMetrics::MetricsStor stor = proc_metrics_.Get();
+ if (metrics_exporter_) {
+ metrics_exporter_->got_proc_metrics(stor, proc_prev_stor_);
+ }
+
+ proc_prev_stor_ = stor;
+}
+
+
+void OTLPAgent::setup_trace_otlp_exporter(
+ exporter::otlp::OtlpHttpExporterOptions& opts) {
+ opts.content_type = exporter::otlp::HttpRequestContentType::kBinary;
+ opts.console_debug = true;
+ otlp_http_exporter_.reset(new exporter::otlp::OtlpHttpExporter(opts));
+}
+
+
+int OTLPAgent::setup_metrics_timer(uint64_t period) {
+ if (period == 0) {
+ return metrics_timer_.stop();
+ }
+
+ // There's no need to stop the timer previously as uv_timer_start() stops the
+ // timer if active.
+ return metrics_timer_.start(metrics_timer_cb_, period, period, this);
+}
+
+void OTLPAgent::update_tracer(uint32_t flags) {
+ tracer_.reset(nullptr);
+ if (flags) {
+ Tracer* tracer = Tracer::CreateInstance(flags, trace_hook_, this);
+ ASSERT_NOT_NULL(tracer);
+ tracer_.reset(tracer);
+ }
+}
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
diff --git a/agents/otlp/src/otlp_agent.h b/agents/otlp/src/otlp_agent.h
new file mode 100644
index 00000000000..fc45e5a1e83
--- /dev/null
+++ b/agents/otlp/src/otlp_agent.h
@@ -0,0 +1,151 @@
+#ifndef AGENTS_OTLP_SRC_OTLP_AGENT_H_
+#define AGENTS_OTLP_SRC_OTLP_AGENT_H_
+
+#include
+#include
+#include
+#include "nlohmann/json.hpp"
+
+#include "asserts-cpp/asserts.h"
+#include "metrics_exporter.h"
+
+
+// Class pre-declaration
+namespace opentelemetry {
+inline namespace v1 {
+namespace exporter {
+namespace otlp {
+class OtlpHttpExporter;
+struct OtlpHttpExporterOptions;
+}
+}
+}
+}
+
+namespace node {
+namespace nsolid {
+
+namespace otlp {
+
+struct JSThreadMetrics {
+ ThreadMetrics metrics_;
+ ThreadMetrics::MetricsStor prev_;
+ explicit JSThreadMetrics(SharedEnvInst envinst): metrics_(envinst),
+ prev_() {}
+};
+
+class OTLPAgent {
+ public:
+ static OTLPAgent* Inst();
+
+ int start();
+
+ int stop();
+
+ int config(const nlohmann::json& config);
+
+ private:
+ OTLPAgent();
+
+ ~OTLPAgent();
+
+ static void run_(nsuv::ns_thread*, OTLPAgent*);
+
+ static void shutdown_cb_(nsuv::ns_async*, OTLPAgent*);
+
+ static void config_agent_cb_(std::string, OTLPAgent*);
+
+ static void config_msg_cb_(nsuv::ns_async*, OTLPAgent*);
+
+ static void env_msg_cb_(nsuv::ns_async*, OTLPAgent*);
+
+ static void on_thread_add_(SharedEnvInst, OTLPAgent* agent);
+
+ static void on_thread_remove_(SharedEnvInst, OTLPAgent* agent);
+
+ static void trace_hook_(Tracer* tracer,
+ const Tracer::SpanStor& stor,
+ OTLPAgent* agent);
+
+ static void span_msg_cb_(nsuv::ns_async*, OTLPAgent* agent);
+
+ static void metrics_timer_cb_(nsuv::ns_timer*, OTLPAgent*);
+
+ static void metrics_msg_cb_(nsuv::ns_async*, OTLPAgent* agent);
+
+ static void thr_metrics_cb_(ThreadMetrics*, OTLPAgent*);
+
+ void do_start();
+
+ void do_stop();
+
+ void config_datadog(const nlohmann::json& config);
+
+ void config_dynatrace(const nlohmann::json& config);
+
+ void config_endpoint(const std::string& type,
+ const nlohmann::json& config);
+
+ void config_newrelic(const nlohmann::json& config);
+
+ void config_otlp_agent(const nlohmann::json& config);
+
+ void config_otlp_endpoint(const nlohmann::json& config);
+
+ void config_service(const nlohmann::json& service);
+
+ void got_proc_metrics();
+
+ void setup_trace_otlp_exporter( // NOLINTNEXTLINE(runtime/references)
+ opentelemetry::v1::exporter::otlp::OtlpHttpExporterOptions& opts);
+
+ int setup_metrics_timer(uint64_t period);
+
+ void update_tracer(uint32_t flags);
+
+ uv_loop_t loop_;
+ nsuv::ns_thread thread_;
+ nsuv::ns_async shutdown_;
+
+ // For otlp thread start synchronization
+ std::atomic ready_;
+ uv_cond_t start_cond_;
+ uv_mutex_t start_lock_;
+
+ nsuv::ns_rwlock exit_lock_;
+
+ bool hooks_init_;
+
+ nsuv::ns_async env_msg_;
+ TSQueue> env_msg_q_;
+
+ // For the Tracing API
+ std::unique_ptr tracer_;
+ nsuv::ns_async span_msg_;
+ TSQueue span_msg_q_;
+ uint32_t trace_flags_;
+
+ std::unique_ptr
+ otlp_http_exporter_;
+
+ // For the Metrics API
+ uint64_t metrics_interval_;
+ ProcessMetrics proc_metrics_;
+ ProcessMetrics::MetricsStor proc_prev_stor_;
+ std::map env_metrics_map_;
+ nsuv::ns_async metrics_msg_;
+ TSQueue thr_metrics_msg_q_;
+ nsuv::ns_timer metrics_timer_;
+ std::unique_ptr metrics_exporter_;
+
+ // For the Configuration API
+ nsuv::ns_async config_msg_;
+ TSQueue config_msg_q_;
+ nlohmann::json config_;
+};
+
+} // namespace otlp
+} // namespace nsolid
+} // namespace node
+
+#endif // AGENTS_OTLP_SRC_OTLP_AGENT_H_
diff --git a/agents/src/http_client.cc b/agents/src/http_client.cc
new file mode 100644
index 00000000000..d0df7a4eb83
--- /dev/null
+++ b/agents/src/http_client.cc
@@ -0,0 +1,172 @@
+#include "http_client.h"
+#include "util.h"
+
+#include
+
+#include "asserts-cpp/asserts.h"
+
+namespace node {
+namespace nsolid {
+
+static const char* const root_certs[] = {
+#include "node_root_certs.h" // NOLINT(build/include_order)
+};
+
+CurlContext::CurlContext(HttpClient* http_client, curl_socket_t sockfd):
+ http_client_(http_client),
+ poll_handle_(new nsuv::ns_poll),
+ sockfd_(sockfd) {
+ CHECK_EQ(0, poll_handle_->init(http_client->loop_, sockfd));
+ poll_handle_->set_data(this);
+}
+
+CurlContext::~CurlContext() {
+ poll_handle_->close_and_delete();
+}
+
+int CurlContext::start(int events, poll_cb cb) {
+ return poll_handle_->start(events, cb);
+}
+
+HttpClient::HttpClient(uv_loop_t* loop): loop_(loop),
+ timeout_(new nsuv::ns_timer) {
+ ASSERT_EQ(0, timeout_->init(loop));
+ timeout_->set_data(this);
+ ASSERT_EQ(0, curl_global_init(CURL_GLOBAL_ALL));
+ curl_handle_ = curl_multi_init();
+ ASSERT_NOT_NULL(curl_handle_);
+ ASSERT_EQ(0, curl_multi_setopt(curl_handle_,
+ CURLMOPT_SOCKETFUNCTION,
+ handle_socket_));
+ ASSERT_EQ(0, curl_multi_setopt(curl_handle_, CURLMOPT_SOCKETDATA, this));
+ ASSERT_EQ(0, curl_multi_setopt(curl_handle_,
+ CURLMOPT_TIMERFUNCTION,
+ start_timeout_));
+ ASSERT_EQ(0, curl_multi_setopt(curl_handle_, CURLMOPT_TIMERDATA, this));
+ for (size_t i = 0; i < node::arraysize(root_certs); i++) {
+ cacert_ += root_certs[i];
+ cacert_ += "\n";
+ }
+}
+
+HttpClient::~HttpClient() {
+ timeout_->close_and_delete();
+ curl_multi_cleanup(curl_handle_);
+}
+
+void HttpClient::check_multi_info() {
+ CURLMsg* message;
+ int pending;
+ std::queue q;
+ while ((message = curl_multi_info_read(curl_handle_, &pending))) {
+ switch (message->msg) {
+ case CURLMSG_DONE:
+ q.push(message);
+ break;
+ default:
+ break;
+ }
+ }
+
+ CURL* easy_handle;
+ while (!q.empty()) {
+ CURLMsg* message = q.front();
+ easy_handle = message->easy_handle;
+ curl_multi_remove_handle(curl_handle_, easy_handle);
+ struct HttpClientStor* stor;
+ curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &stor);
+ stor->client->transfer_done(message, stor);
+ curl_easy_cleanup(easy_handle);
+ q.pop();
+ }
+}
+
+/*static*/int HttpClient::handle_socket_(CURL* easy,
+ curl_socket_t s,
+ int action,
+ void* userp,
+ void* socketp) {
+ CurlContext* context = nullptr;
+ int events = 0;
+ HttpClient* client = reinterpret_cast(userp);
+ switch (action) {
+ case CURL_POLL_IN:
+ case CURL_POLL_OUT:
+ case CURL_POLL_INOUT:
+ context = socketp ? reinterpret_cast(socketp)
+ : new CurlContext(client, s);
+
+ curl_multi_assign(client->curl_handle_, s, context);
+ if (action != CURL_POLL_IN)
+ events |= UV_WRITABLE;
+ if (action != CURL_POLL_OUT)
+ events |= UV_READABLE;
+
+ context->start(events, curl_perform_);
+ break;
+ case CURL_POLL_REMOVE:
+ if (socketp) {
+ context = reinterpret_cast(socketp);
+ delete context;
+ curl_multi_assign(client->curl_handle_, s, nullptr);
+ }
+ break;
+ default:
+ abort();
+ }
+
+ return 0;
+}
+
+/*static*/void HttpClient::on_timeout_(nsuv::ns_timer* timer) {
+ int running_handles;
+ HttpClient* client = timer->get_data();
+ curl_multi_socket_action(client->curl_handle_,
+ CURL_SOCKET_TIMEOUT,
+ 0,
+ &running_handles);
+ client->check_multi_info();
+}
+
+/*static*/int HttpClient::start_timeout_(CURLM* multi,
+ long timeout, // NOLINT(runtime/int)
+ void* userp) {
+ HttpClient* client = reinterpret_cast(userp);
+ if (timeout < 0) {
+ return client->timeout_->stop();
+ } else {
+ if (timeout == 0) {
+ timeout = 1; // 0 means directly call socket_action, but we will do it
+ // in a bit.
+ }
+
+ return client->timeout_->start(on_timeout_, timeout, 0);
+ }
+}
+
+/*static*/void HttpClient::curl_perform_(nsuv::ns_poll* poll,
+ int status,
+ int events) {
+ int running_handles;
+ int flags = 0;
+ CurlContext* context = poll->get_data();
+ if (events & UV_READABLE)
+ flags |= CURL_CSELECT_IN;
+ if (events & UV_WRITABLE)
+ flags |= CURL_CSELECT_OUT;
+
+ HttpClient* client = context->http_client_;
+ curl_multi_socket_action(client->curl_handle_,
+ context->sockfd_,
+ flags,
+ &running_handles);
+ client->check_multi_info();
+}
+
+/*static*/size_t HttpClient::write_cb_(void*, size_t, size_t nmemb, void*) {
+ /* Don't write the response anywhere(by default libcurl prints to stdout) */
+ return nmemb;
+}
+
+} // namespace nsolid
+} // namespace node
diff --git a/agents/src/http_client.h b/agents/src/http_client.h
new file mode 100644
index 00000000000..6a70af1d18a
--- /dev/null
+++ b/agents/src/http_client.h
@@ -0,0 +1,73 @@
+#ifndef AGENTS_COMMON_SRC_HTTP_CLIENT_H_
+#define AGENTS_COMMON_SRC_HTTP_CLIENT_H_
+
+#include
+#include
+
+#include "nsuv-inl.h"
+
+namespace node {
+namespace nsolid {
+
+class HttpClient;
+
+struct HttpClientStor {
+ HttpClient* client;
+ void* data;
+};
+
+class CurlContext {
+ public:
+ using poll_cb = void(*)(nsuv::ns_poll*, int, int);
+
+ explicit CurlContext(HttpClient* http_client, curl_socket_t sockfd);
+ ~CurlContext();
+
+ int start(int events, poll_cb cb);
+
+ private:
+ friend class HttpClient;
+ HttpClient* http_client_;
+ nsuv::ns_poll* poll_handle_;
+ curl_socket_t sockfd_;
+};
+
+class HttpClient {
+ public:
+ explicit HttpClient(uv_loop_t* loop);
+ virtual ~HttpClient();
+
+ virtual void transfer_done(CURLMsg* message, struct HttpClientStor*) {}
+
+ private:
+ static int handle_socket_(CURL* easy,
+ curl_socket_t s,
+ int action,
+ void* userp,
+ void* socketp);
+
+ static void on_timeout_(nsuv::ns_timer* timer);
+
+ // NOLINTNEXTLINE(runtime/int)
+ static int start_timeout_(CURLM* multi, long timeout_ms, void* userp);
+
+ static void curl_perform_(nsuv::ns_poll* poll, int status, int events);
+
+ void check_multi_info();
+
+ protected:
+ static size_t write_cb_(void*, size_t, size_t, void*);
+
+ friend class CurlContext;
+ uv_loop_t* loop_;
+ nsuv::ns_timer* timeout_;
+ CURLM* curl_handle_;
+ std::string cacert_;
+ size_t cacert_size_;
+};
+
+} // namespace nsolid
+} // namespace node
+
+
+#endif // AGENTS_SRC_HTTP_CLIENT_H_
diff --git a/agents/statsd/lib/agent.js b/agents/statsd/lib/agent.js
new file mode 100644
index 00000000000..92431319bca
--- /dev/null
+++ b/agents/statsd/lib/agent.js
@@ -0,0 +1,75 @@
+'use strict';
+
+const { ArrayIsArray } = primordials;
+const { validateStringArray } = require('internal/validators');
+
+module.exports = ({ bucket,
+ config,
+ send,
+ status,
+ start,
+ stop,
+ tags,
+ tcpIp,
+ udpIp }) => {
+ const format = {
+ bucket,
+ tags,
+ counter: function counter(name, value) {
+ return `${bucket()}.${name}:${value}|c${tags()}`;
+ },
+ gauge: function gauge(name, value) {
+ return `${bucket()}.${name}:${value}|g${tags()}`;
+ },
+ set: function set(name, value) {
+ return `${bucket()}.${name}:${value}|s${tags()}`;
+ },
+ timing: function timing(name, value) {
+ return `${bucket()}.${name}:${value}|ms${tags()}`;
+ },
+ };
+
+ function sendRaw(str) {
+ if (typeof str !== 'string') {
+ validateStringArray(str, 'str');
+ }
+
+ if (status() !== 'ready') {
+ return -1;
+ }
+
+ if (udpIp()) {
+ // Split up chunks into lines to handle UDP MTU case.
+ return send(ArrayIsArray(str) ? str : str.split(/\r?\n/g));
+ }
+
+ if (tcpIp()) {
+ return send(ArrayIsArray(str) ? str : [ str ]);
+ }
+
+ return -1;
+ }
+
+ return {
+ config,
+ sendRaw,
+ counter: function counter(name, value) {
+ sendRaw(format.counter(name, value));
+ },
+ gauge: function gauge(name, value) {
+ sendRaw(format.gauge(name, value));
+ },
+ set: function set(name, value) {
+ sendRaw(format.set(name, value));
+ },
+ timing: function timing(name, value) {
+ sendRaw(format.timing(name, value));
+ },
+ status,
+ start,
+ stop,
+ tcpIp,
+ udpIp,
+ format,
+ };
+};
diff --git a/agents/statsd/lib/nsolid.js b/agents/statsd/lib/nsolid.js
new file mode 100644
index 00000000000..2a12d05fca3
--- /dev/null
+++ b/agents/statsd/lib/nsolid.js
@@ -0,0 +1,6 @@
+'use strict';
+
+// Entrypoint for the embedded internal module
+const bindings = internalBinding('nsolid_statsd_agent');
+module.exports =
+ require('internal/agents/statsd/lib/agent')(bindings);
diff --git a/agents/statsd/src/binding.cc b/agents/statsd/src/binding.cc
new file mode 100644
index 00000000000..840f0a3b15c
--- /dev/null
+++ b/agents/statsd/src/binding.cc
@@ -0,0 +1,204 @@
+#include "node_internals.h"
+#include "node_external_reference.h"
+#include "statsd_agent.h"
+#include "util.h"
+
+using v8::Array;
+using v8::Context;
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::Global;
+using v8::HandleScope;
+using v8::Isolate;
+using v8::JSON;
+using v8::Local;
+using v8::NewStringType;
+using v8::Object;
+using v8::String;
+using v8::Value;
+
+namespace node {
+namespace nsolid {
+namespace statsd {
+
+using GFunction = Global;
+using status_cb_pair = std::pair;
+
+static status_cb_pair* status_cb_pair_ = nullptr;
+
+static void at_exit(void*) {
+ delete status_cb_pair_;
+ status_cb_pair_ = nullptr;
+}
+
+static void Bucket(const FunctionCallbackInfo& args) {
+ Isolate* isolate = args.GetIsolate();
+ std::string bucket = StatsDAgent::Inst()->bucket();
+ args.GetReturnValue().Set(
+ String::NewFromUtf8(isolate,
+ bucket.c_str(),
+ NewStringType::kNormal).ToLocalChecked());
+}
+
+static void Status(const FunctionCallbackInfo& args) {
+ Isolate* isolate = args.GetIsolate();
+ args.GetReturnValue().Set(
+ String::NewFromUtf8(isolate,
+ StatsDAgent::Inst()->status().c_str(),
+ NewStringType::kNormal).ToLocalChecked());
+}
+
+static void Send(const FunctionCallbackInfo& args) {
+ Isolate* isolate = args.GetIsolate();
+ Local context = isolate->GetCurrentContext();
+ ASSERT(args[0]->IsArray());
+ Local