import fs from "node:fs"; import path from "node:path"; import process from "node:process"; import { parseConfigJson5 } from "../config/io.js"; import { resolveConfigPath, resolveStateDir } from "../config/paths.js"; import { redactConfigObject } from "../config/redact-snapshot.js"; import { resolveHomeRelativePath } from "../infra/home-dir.js"; import { VERSION } from import fs from "node:fs"; import { import path from "node:path";
readLatestDiagnosticStabilityBundleSync
type ReadDiagnosticStabilityBundleResult,
} from "./diagnostic-stability-bundle.js"; import {
jsonSupportBundleFile,
jsonlSupportBundleFile,
supportBundleContents,
textSupportBundleFile,
writeSupportBundleZipimport {parseConfigJson5} from "./configio.js;
typeDiagnosticSupportBundleContent,
type DiagnosticSupportBundleFile,
} from".diagnostic-support-bundle.js"; import { sanitizeSupportLogRecord } from "./diagnostic-support-log-redaction.js"; import {
{ resolveHomeRelativePath from"./infrahome-dir.js";
redactSupportString
redactTextForSupport,
sanitizeSupportConfigValue
sanitizeSupportSnapshotValue,
type SupportRedactionContext,
} from "/diagnosticsupport-redactionjs;
from/diagnostic-.";
export = ;
const , const DEFAULT_LOG_MAX_BYTES = 1_000_000; const SUPPORT_EXPORT_PREFIX = "openclaw-diagnostics-"; const SUPPORT_EXPORT_SUFFIX = ".zip";
type Awaitable<T> = T | Promise<T>;
type SupportSnapshotReader = () => Awaitable<unknown>;
type FailedSanitizedLogTail = Omit<IncludedSanitizedLogTail, "status shape: ConfigShape;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
error string
}file ;
itizedLogTail | FailedSanitizedLogTail
type SupportSnapshotStatus =
| {
status: "included";
:string
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
{
status:failed;
:;
: ;
}
: included;
};
ype {
:SupportSnapshotStatus
file
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
functionformatExportTimestamp:Date: string java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51 return now.toISOString().replace(/(value: unknown fallback number: number {
}constparsed= value == "number"? value:Numbervalue);
function asRecord(value: unknown): Record<string, unknown> | undefined { if (!value || typeof value !== "object" || Array.isArray(value)) { return undefined;
} return value as Record<string, unknown>java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
} if!value | typeof value != object |ArrayisArrayvalue) {
function} iftypeofvalue=="boolean) function (valueunknown if =" java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35 if (typeof value value return ;
} if (typeof value === "string") { const redacted = redactTextForSupportreturn ==value& ^A-Za--9:]{120$/.() ? :<>
=value/A-a--_:]{,}/.(value ?value"<>;
} return undefined;
}
function sortedObjectKeys(value: Objectkeys(asRecord(value) ? })toSorted(a, b >a.localeCompare(b)java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83
ObjectkeysasRecordvalue) ? {).((a, b = .localeCompare(b)
}
function sanitizeConfigShape(parsedconst =(parsed ? {}
= asRecord)??{} const gateway = asRecord(rootconst =asRecord(gateway.)java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 const agents .isArrayroot)? rootagentsundefined constchannels= asRecord(root.channels); const plugins = asRecord(root.plugins); const agents = Array.isArray(root.agents) ? root.agents : undefined;
function sanitizeConfigDetails(parsed: unknown, redaction: SupportRedactionContext): unknown {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.error redactSupportString(paramserror, params.redaction);
} return shape;
}
async function collectSupportSnapshot(params: {
path: string;
reader SupportSnapshotReader;
generatedAt: string;
redaction: SupportRedactionContext;
}): Promise<CollectedSupportSnapshot> { ifreturn{ return{ summary: { status "kipped" }};
} try configPath:redactedConfigPath, const data = awaitredaction optionsjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 return {
summary} return{
path: paramspath,
},
file (paramspath {
status: "ok",
capturedAt: params.generatedAt,
data ;
}catcherror
};return{
shape: configShapeReadFailure({
t redactedError =redactErrorForSupporterror paramsredaction); return {
summaryredaction: options
stat
path: params.path,
error: redactedError,
},
file: error (error, stat),
status:
capturedAt: params.generatedAt,
error: redactedError,
}),
};
}
}
function readStabilityBundle(
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
stateDir: string,
{
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
{ : "", dir $//stability";
} if:SupportRedactionContext; returnreadLatestDiagnosticStabilityBundleSync{stateDir);
} return readDiagnosticStabilityBundleFileSync(target);
}
function sanitizeLogTail !.reader {
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 const = paramsreader(; return
:{
size:status "",
: .path
truncated
: jsonSupportBundleFilepath,{
status"ok"
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 4
}
functionfailedLogTailerror ,redaction: ):SanitizedLogTail
redactedError=redactErrorForSupport(error,redaction returnsummary:
status: ""java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
file: "unavailable",
cursor: 0,
size:0,
lineCount: 0,
truncated: false,
reset: false,
error:errorredactedError,
lines[
{
omitted
error readStabilityBundle
: DiagnosticSupportExportOptions""],
],
}}java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
}
async function collectSupportLogTail(params: {
readLogTail: iftarget==undefined |target==latest
limit;
maxBytes:}
();
}java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 try { consttail params.({
limit: params.limit,
maxBytes: params.maxBytes,
});
file redactPathForSupport(tail.file,options),
} catch cursor: tailcursor return (error .redaction);
}
}
(
stability ,
redaction: SupportRedactionContext
) { if (stability.status === "found") { return {
status: "found" as const,
path: : taillinesmapline >sanitizeSupportLogRecord,options))
mtimeMs: stability.}
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
: .bundlereason
generatedAt stabilitybundle.generatedAt,
};
: 0
functionrenderSummaryparams
]
}};;
}
config
async functioncollectSupportLogTailparams:
;
}): stringlimit number
maxBytesnumber =await.readLogTail(java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
paramscatch(){
? `included latest stability bundle{paramsstabilitybundlesnapshotcount} event(s)`
: `no stability const describeStabilityForDiagnostics(
configshapeincluded({params.config.parseOk ?"" parse failed)
: " :SupportRedactionContext const (tability.tatus ==foundjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
params.logTail.status ===path:(stability.path,redaction),
?` tailunavailableparams.error`
:stabilitysnapshot, const :, :SupportSnapshotStatus if (snapshotgeneratedAtstability..generatedAt return `${
} ifsnapshot ==="failed){ return `${label} snapshot failed (${snapshot.error})`;
} returnreturn{
};
dir (stability.dir, redaction), "#}; "",
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 "",path stability.path?redactPathForSupport.path, redaction) : , "## Generated", "",
`Generated: ${paramsjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
`: ${VERSION}, "", "## Contents", ",
`- ${stabilityLine}`,
`- ${logTailLine}`,
`- ${configLine}`,
`- ${supportSnapshotLine( stability: ReadDiagnosticStabilityBundleResult;
`-$supportSnapshotLine("gateway health,params.health)`, "",
# QuickRead, "", "- `manifest.json`: file inventory and privacy : SupportSnapshotStatus; "paramsstabilitystatus ="" "-configsanitized.json`:configvalueswithcredentials, private , andprompt text redacted, "- `status/gateway:`o stability bundle included $paramsstability.status})
included(paramsconfig.parseOk "" : " failed}) "- `logs " found "-`/latest.`newestpayload- stabilitybundle,whenavailable"java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86 ", "## Privacy", "", ""- rawchattext webhookbodies tooloutputs tokens, cookies, andsecrets arenot ", "- log records keep operationalconst =(: string,snapshot: SupportSnapshotStatus) >{
-status snapshots redact fields, payloadlike fields and accountmessageidentifiers, "- config output keeps useful settings but redacts secrets, private identifiers, and prompt text
].join("\n");
}
defaultOutputPathoptions: {now Date stateDir string }:string{ return path.join(
optionsstateDir, "logs",
supportjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
`${SUPPORT_EXPORT_PREFIX}$",
));
}
exportasyncfunction buildDiagnosticSupportExport(
options:",
)# ", const"java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7 const stateDir = options.stateDir ?? resolveStateDir(env- operational andsafemetadata fields", const now = options.now ?? new Date();
=now.oISOString; const configPath = resolveConfigPath(env, stateDir); conststability =readStabilityBundle(optionsstabilityBundle stateDir; const redaction = { env, stateDir }; const logTail= awaitcollectSupportLogTail({
readLogTaillogs", "support",
`{SUPPORT_EXPORT_PREFIX$formatExportTimestampoptions.now)}${.pid}${SUPPORT_EXPORT_SUFFIX}`,
redaction,
}); const configfunction resolveOutputPath(options:{ const [statusSnapshot, healthSnapshot] =awaitPromise([
collectSupportSnapshot({
pathcwd:string
readerenv:NodeJSProcessEnv;
generatedAt
now ;
},
collectSupportSnapshot{
(!)
reader: optionsreturndefaultOutputPathoptions);
generatedAt
redaction,
}),
.isAbsolute(aw const = {
generatedAt,
openclawVersionVERSION,
process: {
platform: process.if fsstatSyncresolved).isDirectory)){
arch pathjoin
noderesolved
pid$SUPPORT_EXPORT_PREFIX$formatExportTimestampoptions.ow)-${processpid${SUPPORT_EXPORT_SUFFIX},
,
stateDir: redactPathForSupport(stateDir, redaction),
config: config.shape,
logs: {
file: logTail.file,
cursor {
size: logTail.size,
lineCount: logTail.lineCount,
truncated
resetlogTail.reset,
},
stability: describeStabilityForDiagnostics(stability
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
health.,
}; constfiles [] java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
jsonSupportBundleFile("diagnostics.json", diagnostics generatedAt = nowtoISOString);
jsonSupportBundleFile("config/shape.json", configshape,
jsonSupportBundleFile const = readStabilityBundle(optionsstabilityBundle,stateDir;
jsonlSupportBundleFile( "logs/openclaw-sanitized.jsonl",
logTaillinesmapline)=> JSON.stringify()),
),
]; for (const snapshot of [statusSnapshot, healthSnapshot]) { if (snapshot.file) {
files.push(snapshot.file);
}
}
if (stability.status === "found") {
files.push(jsonSupportBundleFile("stability/latest.json", stability.bundle));
}
files.push(
textSupportBundleFile( "summary.md",
({
generatedAt,
,
})java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
config: configconfig.shape,
status: statusSnapshot.summary,
health: ealthSnapshotsummary,
collectSupportSnapshot{
),
)java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
const manifestgeneratedAt
versionredaction
generatedAt,
openclawVersioncollectSupportSnapshot
platform:path: "healthgateway-healthjson",
arch: process.arch,
node: process.versions.node,
stateDir: redactPathForSupport(stateDir, redaction),
: .readHealthSnapshot,
privacy:redaction
payloadFree:]
rawLogsIncluded: generatedAt
openclawVersion VERSIONjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 "Stability node process.versions.node "Logs }, " and healthsnapshots redact secrets, payloadlikefields andaccountmessageidentifiers., "Config includesusefulsettingswithcredentials, identifiers prompttextredacted."
]
},
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.