@merittdev/horus 0.12.4 → 0.12.5
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/dist/index.cjs +127 -153
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -65880,7 +65880,7 @@ init_cjs_shims();
|
|
|
65880
65880
|
|
|
65881
65881
|
// ../../packages/core/src/version.ts
|
|
65882
65882
|
init_cjs_shims();
|
|
65883
|
-
var HORUS_VERSION = true ? "0.12.
|
|
65883
|
+
var HORUS_VERSION = true ? "0.12.5" : "dev";
|
|
65884
65884
|
var PINNED_SOURCE_VERSION = "2.0.2";
|
|
65885
65885
|
|
|
65886
65886
|
// ../../packages/core/src/evidence.ts
|
|
@@ -121842,6 +121842,120 @@ function extractPort2(hostUrl) {
|
|
|
121842
121842
|
init_cjs_shims();
|
|
121843
121843
|
var import_picocolors44 = __toESM(require_picocolors(), 1);
|
|
121844
121844
|
var DEFAULT_DB_URL4 = "postgresql://horus:horus@localhost:5433/horus";
|
|
121845
|
+
var CONNECTOR_CHECKS = {
|
|
121846
|
+
// Elasticsearch (runtime logs)
|
|
121847
|
+
elasticsearch: {
|
|
121848
|
+
label: "Elasticsearch",
|
|
121849
|
+
absentNext: "add connectors.elasticsearch to an environment in your Horus config for runtime log evidence",
|
|
121850
|
+
check: (es, ctx) => !es.indexPattern ? {
|
|
121851
|
+
label: "Elasticsearch",
|
|
121852
|
+
status: "warn",
|
|
121853
|
+
detail: `${ctx} \u2014 indexPattern not set`,
|
|
121854
|
+
next: "set indexPattern in connectors.elasticsearch"
|
|
121855
|
+
} : {
|
|
121856
|
+
label: "Elasticsearch",
|
|
121857
|
+
status: "pass",
|
|
121858
|
+
detail: `${ctx} \u2014 ${es.indexPattern} [runtime ingestion pending]`
|
|
121859
|
+
}
|
|
121860
|
+
},
|
|
121861
|
+
// Grafana (metrics)
|
|
121862
|
+
grafana: {
|
|
121863
|
+
label: "Grafana",
|
|
121864
|
+
absentNext: "add connectors.grafana to an environment for metric evidence",
|
|
121865
|
+
check: (g4, ctx) => !g4.url ? {
|
|
121866
|
+
label: "Grafana",
|
|
121867
|
+
status: "warn",
|
|
121868
|
+
detail: `${ctx} \u2014 URL not set`,
|
|
121869
|
+
next: "set grafana.url or grafana.urlEnv in your Horus config"
|
|
121870
|
+
} : {
|
|
121871
|
+
label: "Grafana",
|
|
121872
|
+
status: "pass",
|
|
121873
|
+
detail: `${ctx} \u2014 URL configured${g4.dashboard ? ` (${g4.dashboard})` : ""} [runtime ingestion pending]`
|
|
121874
|
+
}
|
|
121875
|
+
},
|
|
121876
|
+
// MongoDB (state)
|
|
121877
|
+
mongodb: {
|
|
121878
|
+
label: "MongoDB",
|
|
121879
|
+
absentNext: "add connectors.mongodb to an environment for database state evidence",
|
|
121880
|
+
check: (m5, ctx) => !m5.url ? {
|
|
121881
|
+
label: "MongoDB",
|
|
121882
|
+
status: "warn",
|
|
121883
|
+
detail: `${ctx} \u2014 URL not set`,
|
|
121884
|
+
next: "set mongodb.url or mongodb.urlEnv in your Horus config"
|
|
121885
|
+
} : {
|
|
121886
|
+
label: "MongoDB",
|
|
121887
|
+
status: "pass",
|
|
121888
|
+
detail: `${ctx} \u2014 ${m5.database} [runtime ingestion pending]`
|
|
121889
|
+
}
|
|
121890
|
+
},
|
|
121891
|
+
// Postgres (state)
|
|
121892
|
+
postgres: {
|
|
121893
|
+
label: "Postgres",
|
|
121894
|
+
absentNext: "add connectors.postgres to an environment for database state evidence",
|
|
121895
|
+
check: (p5, ctx) => !p5.url ? {
|
|
121896
|
+
label: "Postgres",
|
|
121897
|
+
status: "warn",
|
|
121898
|
+
detail: `${ctx} \u2014 URL not set`,
|
|
121899
|
+
next: "set postgres.url or postgres.urlEnv in your Horus config"
|
|
121900
|
+
} : {
|
|
121901
|
+
label: "Postgres",
|
|
121902
|
+
status: "pass",
|
|
121903
|
+
detail: `${ctx} \u2014 ${p5.database ?? p5.schema ?? "postgres"} [runtime ingestion pending]`
|
|
121904
|
+
}
|
|
121905
|
+
},
|
|
121906
|
+
// Sentry (error tracking)
|
|
121907
|
+
sentry: {
|
|
121908
|
+
label: "Sentry",
|
|
121909
|
+
absentNext: "add connectors.sentry to an environment for error-tracking evidence",
|
|
121910
|
+
check: (s5, ctx) => {
|
|
121911
|
+
const tokenSet = s5.authToken || process.env[s5.authTokenEnv ?? "SENTRY_AUTH_TOKEN"];
|
|
121912
|
+
return !tokenSet ? {
|
|
121913
|
+
label: "Sentry",
|
|
121914
|
+
status: "warn",
|
|
121915
|
+
detail: `${ctx} \u2014 auth token not set`,
|
|
121916
|
+
next: "set sentry.authToken or sentry.authTokenEnv (default SENTRY_AUTH_TOKEN) in your Horus config"
|
|
121917
|
+
} : {
|
|
121918
|
+
label: "Sentry",
|
|
121919
|
+
status: "pass",
|
|
121920
|
+
detail: `${ctx} \u2014 ${s5.org}/${s5.project} [runtime ingestion pending]`
|
|
121921
|
+
};
|
|
121922
|
+
}
|
|
121923
|
+
},
|
|
121924
|
+
// Axiom (structured logs) — HOR-437: previously omitted from doctor entirely.
|
|
121925
|
+
axiom: {
|
|
121926
|
+
label: "Axiom",
|
|
121927
|
+
absentNext: "add connectors.axiom to an environment for structured log evidence",
|
|
121928
|
+
check: (a2, ctx) => {
|
|
121929
|
+
const tokenSet = a2.token || process.env[a2.tokenEnv ?? "AXIOM_TOKEN"];
|
|
121930
|
+
return !tokenSet ? {
|
|
121931
|
+
label: "Axiom",
|
|
121932
|
+
status: "warn",
|
|
121933
|
+
detail: `${ctx} \u2014 API token not set`,
|
|
121934
|
+
next: "set axiom.token or axiom.tokenEnv (default AXIOM_TOKEN) in your Horus config"
|
|
121935
|
+
} : {
|
|
121936
|
+
label: "Axiom",
|
|
121937
|
+
status: "pass",
|
|
121938
|
+
detail: `${ctx} \u2014 ${a2.dataset} [runtime ingestion pending]`
|
|
121939
|
+
};
|
|
121940
|
+
}
|
|
121941
|
+
},
|
|
121942
|
+
// Redis / BullMQ (queue + cache/state)
|
|
121943
|
+
redis: {
|
|
121944
|
+
label: "Redis",
|
|
121945
|
+
absentNext: "add connectors.redis to an environment for queue state evidence",
|
|
121946
|
+
check: (r, ctx) => !r.url ? {
|
|
121947
|
+
label: "Redis",
|
|
121948
|
+
status: "warn",
|
|
121949
|
+
detail: `${ctx} \u2014 URL not set`,
|
|
121950
|
+
next: "set redis.url or redis.urlEnv in your Horus config"
|
|
121951
|
+
} : {
|
|
121952
|
+
label: "Redis",
|
|
121953
|
+
status: "pass",
|
|
121954
|
+
detail: `${ctx} \u2014 URL configured [runtime ingestion pending]`
|
|
121955
|
+
}
|
|
121956
|
+
}
|
|
121957
|
+
};
|
|
121958
|
+
var DOCTOR_CONNECTOR_KEYS = Object.keys(CONNECTOR_CHECKS);
|
|
121845
121959
|
function mark2(status) {
|
|
121846
121960
|
if (status === "pass") return import_picocolors44.default.green("\u2713");
|
|
121847
121961
|
if (status === "warn") return import_picocolors44.default.yellow("~");
|
|
@@ -121943,168 +122057,28 @@ async function runDoctor(opts) {
|
|
|
121943
122057
|
}
|
|
121944
122058
|
try {
|
|
121945
122059
|
const globalConfig2 = await loadConfig(opts?.config, { cwd });
|
|
121946
|
-
|
|
121947
|
-
let anyGrafana = false;
|
|
121948
|
-
let anyMongo = false;
|
|
121949
|
-
let anyPostgres = false;
|
|
121950
|
-
let anySentry = false;
|
|
121951
|
-
let anyRedis = false;
|
|
122060
|
+
const configured = /* @__PURE__ */ new Set();
|
|
121952
122061
|
for (const project of globalConfig2.projects) {
|
|
121953
122062
|
for (const env of project.environments) {
|
|
121954
122063
|
const ctx = `${project.name}/${env.name}`;
|
|
121955
122064
|
const c4 = env.connectors;
|
|
121956
|
-
|
|
121957
|
-
|
|
121958
|
-
if (
|
|
121959
|
-
|
|
121960
|
-
|
|
121961
|
-
|
|
121962
|
-
detail: `${ctx} \u2014 indexPattern not set`,
|
|
121963
|
-
next: "set indexPattern in connectors.elasticsearch"
|
|
121964
|
-
});
|
|
121965
|
-
} else {
|
|
121966
|
-
checks.push({
|
|
121967
|
-
label: "Elasticsearch",
|
|
121968
|
-
status: "pass",
|
|
121969
|
-
detail: `${ctx} \u2014 ${c4.elasticsearch.indexPattern} [runtime ingestion pending]`
|
|
121970
|
-
});
|
|
121971
|
-
}
|
|
121972
|
-
}
|
|
121973
|
-
if (c4.grafana) {
|
|
121974
|
-
anyGrafana = true;
|
|
121975
|
-
if (!c4.grafana.url) {
|
|
121976
|
-
checks.push({
|
|
121977
|
-
label: "Grafana",
|
|
121978
|
-
status: "warn",
|
|
121979
|
-
detail: `${ctx} \u2014 URL not set`,
|
|
121980
|
-
next: "set grafana.url or grafana.urlEnv in your Horus config"
|
|
121981
|
-
});
|
|
121982
|
-
} else {
|
|
121983
|
-
const dashHint = c4.grafana.dashboard ? ` (${c4.grafana.dashboard})` : "";
|
|
121984
|
-
checks.push({
|
|
121985
|
-
label: "Grafana",
|
|
121986
|
-
status: "pass",
|
|
121987
|
-
detail: `${ctx} \u2014 URL configured${dashHint} [runtime ingestion pending]`
|
|
121988
|
-
});
|
|
121989
|
-
}
|
|
121990
|
-
}
|
|
121991
|
-
if (c4.mongodb) {
|
|
121992
|
-
anyMongo = true;
|
|
121993
|
-
if (!c4.mongodb.url) {
|
|
121994
|
-
checks.push({
|
|
121995
|
-
label: "MongoDB",
|
|
121996
|
-
status: "warn",
|
|
121997
|
-
detail: `${ctx} \u2014 URL not set`,
|
|
121998
|
-
next: "set mongodb.url or mongodb.urlEnv in your Horus config"
|
|
121999
|
-
});
|
|
122000
|
-
} else {
|
|
122001
|
-
checks.push({
|
|
122002
|
-
label: "MongoDB",
|
|
122003
|
-
status: "pass",
|
|
122004
|
-
detail: `${ctx} \u2014 ${c4.mongodb.database} [runtime ingestion pending]`
|
|
122005
|
-
});
|
|
122006
|
-
}
|
|
122007
|
-
}
|
|
122008
|
-
if (c4.postgres) {
|
|
122009
|
-
anyPostgres = true;
|
|
122010
|
-
if (!c4.postgres.url) {
|
|
122011
|
-
checks.push({
|
|
122012
|
-
label: "Postgres",
|
|
122013
|
-
status: "warn",
|
|
122014
|
-
detail: `${ctx} \u2014 URL not set`,
|
|
122015
|
-
next: "set postgres.url or postgres.urlEnv in your Horus config"
|
|
122016
|
-
});
|
|
122017
|
-
} else {
|
|
122018
|
-
checks.push({
|
|
122019
|
-
label: "Postgres",
|
|
122020
|
-
status: "pass",
|
|
122021
|
-
detail: `${ctx} \u2014 ${c4.postgres.database ?? c4.postgres.schema ?? "postgres"} [runtime ingestion pending]`
|
|
122022
|
-
});
|
|
122023
|
-
}
|
|
122024
|
-
}
|
|
122025
|
-
if (c4.sentry) {
|
|
122026
|
-
anySentry = true;
|
|
122027
|
-
const tokenSet = c4.sentry.authToken || process.env[c4.sentry.authTokenEnv ?? "SENTRY_AUTH_TOKEN"];
|
|
122028
|
-
if (!tokenSet) {
|
|
122029
|
-
checks.push({
|
|
122030
|
-
label: "Sentry",
|
|
122031
|
-
status: "warn",
|
|
122032
|
-
detail: `${ctx} \u2014 auth token not set`,
|
|
122033
|
-
next: "set sentry.authToken or sentry.authTokenEnv (default SENTRY_AUTH_TOKEN) in your Horus config"
|
|
122034
|
-
});
|
|
122035
|
-
} else {
|
|
122036
|
-
checks.push({
|
|
122037
|
-
label: "Sentry",
|
|
122038
|
-
status: "pass",
|
|
122039
|
-
detail: `${ctx} \u2014 ${c4.sentry.org}/${c4.sentry.project} [runtime ingestion pending]`
|
|
122040
|
-
});
|
|
122041
|
-
}
|
|
122042
|
-
}
|
|
122043
|
-
if (c4.redis) {
|
|
122044
|
-
anyRedis = true;
|
|
122045
|
-
if (!c4.redis.url) {
|
|
122046
|
-
checks.push({
|
|
122047
|
-
label: "Redis",
|
|
122048
|
-
status: "warn",
|
|
122049
|
-
detail: `${ctx} \u2014 URL not set`,
|
|
122050
|
-
next: "set redis.url or redis.urlEnv in your Horus config"
|
|
122051
|
-
});
|
|
122052
|
-
} else {
|
|
122053
|
-
checks.push({
|
|
122054
|
-
label: "Redis",
|
|
122055
|
-
status: "pass",
|
|
122056
|
-
detail: `${ctx} \u2014 URL configured [runtime ingestion pending]`
|
|
122057
|
-
});
|
|
122058
|
-
}
|
|
122065
|
+
for (const key of DOCTOR_CONNECTOR_KEYS) {
|
|
122066
|
+
const cfg = c4[key];
|
|
122067
|
+
if (cfg === void 0) continue;
|
|
122068
|
+
configured.add(key);
|
|
122069
|
+
const run3 = CONNECTOR_CHECKS[key].check;
|
|
122070
|
+
checks.push(run3(cfg, ctx));
|
|
122059
122071
|
}
|
|
122060
122072
|
}
|
|
122061
122073
|
}
|
|
122062
|
-
|
|
122063
|
-
|
|
122064
|
-
|
|
122065
|
-
status: "warn",
|
|
122066
|
-
detail: "not configured",
|
|
122067
|
-
next: "add connectors.elasticsearch to an environment in your Horus config for runtime log evidence"
|
|
122068
|
-
});
|
|
122069
|
-
}
|
|
122070
|
-
if (!anyGrafana) {
|
|
122071
|
-
checks.push({
|
|
122072
|
-
label: "Grafana",
|
|
122073
|
-
status: "warn",
|
|
122074
|
-
detail: "not configured",
|
|
122075
|
-
next: "add connectors.grafana to an environment for metric evidence"
|
|
122076
|
-
});
|
|
122077
|
-
}
|
|
122078
|
-
if (!anyMongo) {
|
|
122079
|
-
checks.push({
|
|
122080
|
-
label: "MongoDB",
|
|
122081
|
-
status: "warn",
|
|
122082
|
-
detail: "not configured",
|
|
122083
|
-
next: "add connectors.mongodb to an environment for database state evidence"
|
|
122084
|
-
});
|
|
122085
|
-
}
|
|
122086
|
-
if (!anyPostgres) {
|
|
122074
|
+
for (const key of DOCTOR_CONNECTOR_KEYS) {
|
|
122075
|
+
if (configured.has(key)) continue;
|
|
122076
|
+
const desc2 = CONNECTOR_CHECKS[key];
|
|
122087
122077
|
checks.push({
|
|
122088
|
-
label:
|
|
122089
|
-
status: "warn",
|
|
122090
|
-
detail: "not configured",
|
|
122091
|
-
next: "add connectors.postgres to an environment for database state evidence"
|
|
122092
|
-
});
|
|
122093
|
-
}
|
|
122094
|
-
if (!anySentry) {
|
|
122095
|
-
checks.push({
|
|
122096
|
-
label: "Sentry",
|
|
122097
|
-
status: "warn",
|
|
122098
|
-
detail: "not configured",
|
|
122099
|
-
next: "add connectors.sentry to an environment for error-tracking evidence"
|
|
122100
|
-
});
|
|
122101
|
-
}
|
|
122102
|
-
if (!anyRedis) {
|
|
122103
|
-
checks.push({
|
|
122104
|
-
label: "Redis",
|
|
122078
|
+
label: desc2.label,
|
|
122105
122079
|
status: "warn",
|
|
122106
122080
|
detail: "not configured",
|
|
122107
|
-
next:
|
|
122081
|
+
next: desc2.absentNext
|
|
122108
122082
|
});
|
|
122109
122083
|
}
|
|
122110
122084
|
} catch {
|