@deliciousmonster/datadog-agent-binary 7.82.1-next.3 → 7.82.1-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/runtime/supervisor.js +61 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deliciousmonster/datadog-agent-binary",
|
|
3
|
-
"version": "7.82.1-next.
|
|
3
|
+
"version": "7.82.1-next.4",
|
|
4
4
|
"description": "Harper component that runs the Datadog trace-agent and core-agent alongside a node, with pre-built binaries installed per platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"author": "",
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@deliciousmonster/harper-process-guard": "0.1.0-next.
|
|
41
|
+
"@deliciousmonster/harper-process-guard": "0.1.0-next.3"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^26.0.0",
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
},
|
|
69
69
|
"homepage": "https://github.com/deliciousmonster/datadog-agent-binary#readme",
|
|
70
70
|
"optionalDependencies": {
|
|
71
|
-
"@deliciousmonster/datadog-agent-binary-linux-x86_64": "7.82.1-next.
|
|
72
|
-
"@deliciousmonster/datadog-agent-binary-linux-arm64": "7.82.1-next.
|
|
73
|
-
"@deliciousmonster/datadog-agent-binary-macos-arm64": "7.82.1-next.
|
|
74
|
-
"@deliciousmonster/datadog-agent-binary-windows-x86_64": "7.82.1-next.
|
|
71
|
+
"@deliciousmonster/datadog-agent-binary-linux-x86_64": "7.82.1-next.4",
|
|
72
|
+
"@deliciousmonster/datadog-agent-binary-linux-arm64": "7.82.1-next.4",
|
|
73
|
+
"@deliciousmonster/datadog-agent-binary-macos-arm64": "7.82.1-next.4",
|
|
74
|
+
"@deliciousmonster/datadog-agent-binary-windows-x86_64": "7.82.1-next.4"
|
|
75
75
|
},
|
|
76
76
|
"lint-staged": {
|
|
77
77
|
"*.{ts,js,json}": [
|
package/runtime/supervisor.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
// Who holds the agents up. Released Harper has no sidecar API, so the bundled guard is the other half; one
|
|
2
2
|
// agent per node comes from a PID lock either way and only the holder changes.
|
|
3
3
|
|
|
4
|
+
import { readFileSync, unlinkSync } from "node:fs";
|
|
4
5
|
import { join } from "node:path";
|
|
5
6
|
|
|
6
7
|
// Pinned to one exact version, never a range: Harper runs `npm install` when it installs a component, so a
|
|
7
8
|
// caret here would let a customer's node resolve a guard no test in this repo has run against.
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
argvOf,
|
|
11
|
+
fingerprint,
|
|
12
|
+
guard,
|
|
13
|
+
identify as identifyPid,
|
|
14
|
+
} from "@deliciousmonster/harper-process-guard";
|
|
9
15
|
import { describeSpawnFailure } from "./agent-exit.js";
|
|
10
16
|
import { writeConfigFiles } from "./config.js";
|
|
11
17
|
|
|
@@ -99,12 +105,66 @@ const harperSupervisor = (scope, log) => ({
|
|
|
99
105
|
// directory would collide on; this one names the package rather than taking the guard's generic default.
|
|
100
106
|
const REAPER_NAME = "datadog-agent-reaper";
|
|
101
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Harper's own spawn keeps a pid file per process name under <root>/pids and, when the file names a pid
|
|
110
|
+
* that answers kill(pid, 0), returns that pid instead of spawning. After a restart the kernel reissues
|
|
111
|
+
* pids, and a thread of Harper itself answers for one, so the file has to go before the guard asks.
|
|
112
|
+
* Removing it signals nothing. A file naming the real process, or a dead one, is Harper's to keep.
|
|
113
|
+
*
|
|
114
|
+
* @param {string | null} root @param {Array<{ name: string; argv?: readonly string[]; script?: string }>} named
|
|
115
|
+
* @param {import("./log.js").Log} log
|
|
116
|
+
*/
|
|
117
|
+
export function clearStaleHarperPidFiles(root, named, log) {
|
|
118
|
+
if (!root) return;
|
|
119
|
+
for (const { name, argv, script } of named) {
|
|
120
|
+
const file = join(root, "pids", `${name}.pid`);
|
|
121
|
+
let pid;
|
|
122
|
+
try {
|
|
123
|
+
pid = Number.parseInt(readFileSync(file, "utf-8"), 10);
|
|
124
|
+
} catch {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
128
|
+
const running = argvOf(pid);
|
|
129
|
+
if (running === null) continue;
|
|
130
|
+
const ours = argv
|
|
131
|
+
? identifyPid(pid, argv) === "match"
|
|
132
|
+
: running.some((argument) => argument.endsWith(script ?? "\u0000"));
|
|
133
|
+
if (ours) continue;
|
|
134
|
+
try {
|
|
135
|
+
unlinkSync(file);
|
|
136
|
+
log.warn(
|
|
137
|
+
`Datadog supervisor: removed ${file}, Harper's own pid file for ${name}: it named pid ${pid}, which ` +
|
|
138
|
+
`is running \`${running.join(" ")}\`, and Harper would have handed that pid back as the ${name} ` +
|
|
139
|
+
`instead of starting one.`
|
|
140
|
+
);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
log.error(
|
|
143
|
+
`Datadog supervisor: could not remove ${file}, which names pid ${pid} running something else: ` +
|
|
144
|
+
`${error.message}. Harper will hand that pid back as the ${name} rather than start one.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
102
150
|
/** The bundled guard, one call for both agents. `spawn` is the entry module's own, which is the one Harper constrains. */
|
|
103
151
|
const guardSupervisor = (log, spawn) => ({
|
|
104
152
|
kind: "guard",
|
|
105
153
|
async start(agents, { runtime, configFiles, fingerprintParts }) {
|
|
106
154
|
// Harper's start() writes these itself; on this path nothing else will, and both agents read them.
|
|
107
155
|
writeConfigFiles(configFiles, log);
|
|
156
|
+
clearStaleHarperPidFiles(
|
|
157
|
+
runtime.root,
|
|
158
|
+
[
|
|
159
|
+
...agents.map((agent) => ({
|
|
160
|
+
name: agent.name,
|
|
161
|
+
argv: [agent.command, ...agent.args],
|
|
162
|
+
})),
|
|
163
|
+
// The guard builds the reaper's own argv; its script name is the one stable thing to match on.
|
|
164
|
+
{ name: REAPER_NAME, script: "/reaper.js" },
|
|
165
|
+
],
|
|
166
|
+
log
|
|
167
|
+
);
|
|
108
168
|
let result;
|
|
109
169
|
try {
|
|
110
170
|
result = await guard({
|