Skip to content

Commit d47a42a

Browse files
authored
Revert "feat: added monitoring for postgres query result (#6736)"
This reverts commit d7296c6.
1 parent 0d64cd6 commit d47a42a

File tree

2 files changed

+6
-308
lines changed

2 files changed

+6
-308
lines changed

server/monitor-types/postgres.js

Lines changed: 6 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -3,61 +3,26 @@ const { log, UP } = require("../../src/util");
33
const dayjs = require("dayjs");
44
const postgresConParse = require("pg-connection-string").parse;
55
const { Client } = require("pg");
6-
const { ConditionVariable } = require("../monitor-conditions/variables");
7-
const { defaultStringOperators } = require("../monitor-conditions/operators");
8-
const { ConditionExpressionGroup } = require("../monitor-conditions/expression");
9-
const { evaluateExpressionGroup } = require("../monitor-conditions/evaluator");
106

117
class PostgresMonitorType extends MonitorType {
128
name = "postgres";
139

14-
supportsConditions = true;
15-
conditionVariables = [new ConditionVariable("result", defaultStringOperators)];
16-
1710
/**
1811
* @inheritdoc
1912
*/
2013
async check(monitor, heartbeat, _server) {
14+
let startTime = dayjs().valueOf();
15+
2116
let query = monitor.databaseQuery;
2217
// No query provided by user, use SELECT 1
2318
if (!query || (typeof query === "string" && query.trim() === "")) {
2419
query = "SELECT 1";
2520
}
21+
await this.postgresQuery(monitor.databaseConnectionString, query);
2622

27-
const conditions = monitor.conditions ? ConditionExpressionGroup.fromMonitor(monitor) : null;
28-
const hasConditions = conditions && conditions.children && conditions.children.length > 0;
29-
30-
const startTime = dayjs().valueOf();
31-
32-
try {
33-
if (hasConditions) {
34-
// When conditions are enabled, expect a single value result
35-
const result = await this.postgresQuerySingleValue(monitor.databaseConnectionString, query);
36-
heartbeat.ping = dayjs().valueOf() - startTime;
37-
38-
const conditionsResult = evaluateExpressionGroup(conditions, { result: String(result) });
39-
40-
if (!conditionsResult) {
41-
throw new Error(`Query result did not meet the specified conditions (${result})`);
42-
}
43-
44-
heartbeat.status = UP;
45-
heartbeat.msg = "Query did meet specified conditions";
46-
} else {
47-
// Backwards compatible: just check connection and return row count
48-
const result = await this.postgresQuery(monitor.databaseConnectionString, query);
49-
heartbeat.ping = dayjs().valueOf() - startTime;
50-
heartbeat.status = UP;
51-
heartbeat.msg = result;
52-
}
53-
} catch (error) {
54-
heartbeat.ping = dayjs().valueOf() - startTime;
55-
// Re-throw condition errors as-is, wrap database errors
56-
if (error.message.includes("did not meet the specified conditions")) {
57-
throw error;
58-
}
59-
throw new Error(`Database connection/query failed: ${error.message}`);
60-
}
23+
heartbeat.msg = "";
24+
heartbeat.status = UP;
25+
heartbeat.ping = dayjs().valueOf() - startTime;
6126
}
6227

6328
/**
@@ -111,75 +76,6 @@ class PostgresMonitorType extends MonitorType {
11176
});
11277
});
11378
}
114-
115-
/**
116-
* Run a query on Postgres
117-
* @param {string} connectionString The database connection string
118-
* @param {string} query The query to validate the database with
119-
* @returns {Promise<(string[] | object[] | object)>} Response from
120-
* server
121-
*/
122-
async postgresQuerySingleValue(connectionString, query) {
123-
return new Promise((resolve, reject) => {
124-
const config = postgresConParse(connectionString);
125-
126-
// Fix #3868, which true/false is not parsed to boolean
127-
if (typeof config.ssl === "string") {
128-
config.ssl = config.ssl === "true";
129-
}
130-
131-
if (config.password === "") {
132-
// See https://github.com/brianc/node-postgres/issues/1927
133-
reject(new Error("Password is undefined."));
134-
return;
135-
}
136-
const client = new Client(config);
137-
138-
client.on("error", (error) => {
139-
log.debug(this.name, "Error caught in the error event handler.");
140-
reject(error);
141-
});
142-
143-
client.connect((err) => {
144-
if (err) {
145-
reject(err);
146-
client.end();
147-
} else {
148-
// Connected here
149-
try {
150-
client.query(query, (err, res) => {
151-
if (err) {
152-
reject(err);
153-
} else {
154-
// Check if we have results
155-
if (!res.rows || res.rows.length === 0) {
156-
reject(new Error("Query returned no results"));
157-
return;
158-
}
159-
// Check if we have multiple rows
160-
if (res.rows.length > 1) {
161-
reject(new Error("Multiple values were found, expected only one value"));
162-
return;
163-
}
164-
const firstRow = res.rows[0];
165-
const columnNames = Object.keys(firstRow);
166-
// Check if we have multiple columns
167-
if (columnNames.length > 1) {
168-
reject(new Error("Multiple columns were found, expected only one value"));
169-
return;
170-
}
171-
resolve(firstRow[columnNames[0]]);
172-
}
173-
client.end();
174-
});
175-
} catch (e) {
176-
reject(e);
177-
client.end();
178-
}
179-
}
180-
});
181-
});
182-
}
18379
}
18480

18581
module.exports = {

test/backend-test/monitors/test-postgres.js

Lines changed: 0 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -49,203 +49,5 @@ describe(
4949

5050
await assert.rejects(postgresMonitor.check(monitor, heartbeat, {}), regex);
5151
});
52-
53-
test("check() sets status to UP when custom query returns single value", async () => {
54-
// The default timeout of 30 seconds might not be enough for the container to start
55-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
56-
.withStartupTimeout(60000)
57-
.start();
58-
59-
const postgresMonitor = new PostgresMonitorType();
60-
const monitor = {
61-
databaseConnectionString: postgresContainer.getConnectionUri(),
62-
databaseQuery: "SELECT 42",
63-
conditions: "[]",
64-
};
65-
66-
const heartbeat = {
67-
msg: "",
68-
status: PENDING,
69-
};
70-
71-
try {
72-
await postgresMonitor.check(monitor, heartbeat, {});
73-
assert.strictEqual(heartbeat.status, UP, `Expected status ${UP} but got ${heartbeat.status}`);
74-
} finally {
75-
await postgresContainer.stop();
76-
}
77-
});
78-
test("check() sets status to UP when custom query result meets condition", async () => {
79-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
80-
.withStartupTimeout(60000)
81-
.start();
82-
83-
const postgresMonitor = new PostgresMonitorType();
84-
const monitor = {
85-
databaseConnectionString: postgresContainer.getConnectionUri(),
86-
databaseQuery: "SELECT 42 AS value",
87-
conditions: JSON.stringify([
88-
{
89-
type: "expression",
90-
andOr: "and",
91-
variable: "result",
92-
operator: "equals",
93-
value: "42",
94-
},
95-
]),
96-
};
97-
98-
const heartbeat = {
99-
msg: "",
100-
status: PENDING,
101-
};
102-
103-
try {
104-
await postgresMonitor.check(monitor, heartbeat, {});
105-
assert.strictEqual(heartbeat.status, UP, `Expected status ${UP} but got ${heartbeat.status}`);
106-
} finally {
107-
await postgresContainer.stop();
108-
}
109-
});
110-
test("check() rejects when custom query result does not meet condition", async () => {
111-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
112-
.withStartupTimeout(60000)
113-
.start();
114-
115-
const postgresMonitor = new PostgresMonitorType();
116-
const monitor = {
117-
databaseConnectionString: postgresContainer.getConnectionUri(),
118-
databaseQuery: "SELECT 99 AS value",
119-
conditions: JSON.stringify([
120-
{
121-
type: "expression",
122-
andOr: "and",
123-
variable: "result",
124-
operator: "equals",
125-
value: "42",
126-
},
127-
]),
128-
};
129-
130-
const heartbeat = {
131-
msg: "",
132-
status: PENDING,
133-
};
134-
135-
try {
136-
await assert.rejects(
137-
postgresMonitor.check(monitor, heartbeat, {}),
138-
new Error("Query result did not meet the specified conditions (99)")
139-
);
140-
assert.strictEqual(heartbeat.status, PENDING, `Expected status should not be ${heartbeat.status}`);
141-
} finally {
142-
await postgresContainer.stop();
143-
}
144-
});
145-
test("check() rejects when query returns no results with conditions", async () => {
146-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
147-
.withStartupTimeout(60000)
148-
.start();
149-
150-
const postgresMonitor = new PostgresMonitorType();
151-
const monitor = {
152-
databaseConnectionString: postgresContainer.getConnectionUri(),
153-
databaseQuery: "SELECT 1 WHERE 1 = 0",
154-
conditions: JSON.stringify([
155-
{
156-
type: "expression",
157-
andOr: "and",
158-
variable: "result",
159-
operator: "equals",
160-
value: "1",
161-
},
162-
]),
163-
};
164-
165-
const heartbeat = {
166-
msg: "",
167-
status: PENDING,
168-
};
169-
170-
try {
171-
await assert.rejects(
172-
postgresMonitor.check(monitor, heartbeat, {}),
173-
new Error("Database connection/query failed: Query returned no results")
174-
);
175-
assert.strictEqual(heartbeat.status, PENDING, `Expected status should not be ${heartbeat.status}`);
176-
} finally {
177-
await postgresContainer.stop();
178-
}
179-
});
180-
test("check() rejects when query returns multiple rows with conditions", async () => {
181-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
182-
.withStartupTimeout(60000)
183-
.start();
184-
185-
const postgresMonitor = new PostgresMonitorType();
186-
const monitor = {
187-
databaseConnectionString: postgresContainer.getConnectionUri(),
188-
databaseQuery: "SELECT 1 UNION ALL SELECT 2",
189-
conditions: JSON.stringify([
190-
{
191-
type: "expression",
192-
andOr: "and",
193-
variable: "result",
194-
operator: "equals",
195-
value: "1",
196-
},
197-
]),
198-
};
199-
200-
const heartbeat = {
201-
msg: "",
202-
status: PENDING,
203-
};
204-
205-
try {
206-
await assert.rejects(
207-
postgresMonitor.check(monitor, heartbeat, {}),
208-
new Error("Database connection/query failed: Multiple values were found, expected only one value")
209-
);
210-
assert.strictEqual(heartbeat.status, PENDING, `Expected status should not be ${heartbeat.status}`);
211-
} finally {
212-
await postgresContainer.stop();
213-
}
214-
});
215-
test("check() rejects when query returns multiple columns with conditions", async () => {
216-
const postgresContainer = await new PostgreSqlContainer("postgres:latest")
217-
.withStartupTimeout(60000)
218-
.start();
219-
220-
const postgresMonitor = new PostgresMonitorType();
221-
const monitor = {
222-
databaseConnectionString: postgresContainer.getConnectionUri(),
223-
databaseQuery: "SELECT 1 AS col1, 2 AS col2",
224-
conditions: JSON.stringify([
225-
{
226-
type: "expression",
227-
andOr: "and",
228-
variable: "result",
229-
operator: "equals",
230-
value: "1",
231-
},
232-
]),
233-
};
234-
235-
const heartbeat = {
236-
msg: "",
237-
status: PENDING,
238-
};
239-
240-
try {
241-
await assert.rejects(
242-
postgresMonitor.check(monitor, heartbeat, {}),
243-
new Error("Database connection/query failed: Multiple columns were found, expected only one value")
244-
);
245-
assert.strictEqual(heartbeat.status, PENDING, `Expected status should not be ${heartbeat.status}`);
246-
} finally {
247-
await postgresContainer.stop();
248-
}
249-
});
25052
}
25153
);

0 commit comments

Comments
 (0)