Skip to content

Commit 1c2f034

Browse files
committed
Wrap node-postgres
1 parent 5cf9cd1 commit 1c2f034

File tree

11 files changed

+323
-153
lines changed

11 files changed

+323
-153
lines changed

instrumentation-wasm/src/js_transformer/transformer.rs

Lines changed: 19 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use oxc_allocator::Allocator;
2-
use oxc_ast::ast::MethodDefinition;
1+
use oxc_allocator::{Allocator, Box};
2+
use oxc_ast::ast::{FunctionBody, MethodDefinition};
33
use oxc_codegen::{Codegen, CodegenOptions};
44
use oxc_parser::{ParseOptions, Parser};
55
use oxc_semantic::SemanticBuilder;
@@ -48,9 +48,6 @@ pub fn transform_code_str(code: &str, instructions_json: &str, src_type: i32) ->
4848
let t = &mut Transformer {
4949
allocator: &allocator,
5050
file_instructions: &file_instructions,
51-
//current_function_identifier: None,
52-
//modify_return_value: false,
53-
//sub_function_counter: 0,
5451
};
5552

5653
traverse_mut(t, &allocator, program, symbols, scopes);
@@ -77,18 +74,12 @@ pub fn transform_code_str(code: &str, instructions_json: &str, src_type: i32) ->
7774
})
7875
.build(&program);
7976

80-
// Debug helper
81-
//format!("{:?}", parser_result.program);
82-
8377
js.code
8478
}
8579

8680
struct Transformer<'a> {
8781
allocator: &'a Allocator,
8882
file_instructions: &'a FileInstructions,
89-
//current_function_identifier: Option<String>, // Only set if we want to instrument the current function
90-
//sub_function_counter: i32, // Counter to keep track of how many sub functions we are in
91-
//modify_return_value: bool,
9283
}
9384

9485
impl<'a> Traverse<'a> for Transformer<'a> {
@@ -106,8 +97,6 @@ impl<'a> Traverse<'a> for Transformer<'a> {
10697
return;
10798
}
10899

109-
// Todo implement submethod counting for nested functions for supporting modifications of return value
110-
111100
let method_name = node.key.name().unwrap().to_string();
112101

113102
let found_instruction = self
@@ -117,17 +106,11 @@ impl<'a> Traverse<'a> for Transformer<'a> {
117106
.find(|f| f.node_type == "MethodDefinition" && f.name == method_name);
118107

119108
if found_instruction.is_none() {
120-
//self.current_function_identifier = None;
121-
//self.modify_return_value = false;
122109
return;
123110
}
124111

125112
let instruction = found_instruction.unwrap();
126113

127-
/*let function_identifier = format!("{}.{}", self.module_name, method_name);
128-
self.current_function_identifier = Some(function_identifier.clone());
129-
self.modify_return_value = instruction.modify_return_value;*/
130-
131114
// We need to collect the arg names before we make the body mutable
132115
let arg_names = if instruction.modify_args {
133116
// Todo check whats appens if rest parameter is used
@@ -149,13 +132,7 @@ impl<'a> Traverse<'a> for Transformer<'a> {
149132
arg_names_str, instruction.identifier, arg_names_str
150133
));
151134

152-
body.statements.insert(
153-
0,
154-
parse_js_code_to_statements(self.allocator, &source_text, SourceType::mjs())
155-
.into_iter()
156-
.next()
157-
.unwrap(),
158-
);
135+
insert_single_statement_into_func(self.allocator, body, 0, &source_text);
159136
}
160137

161138
if instruction.inspect_args {
@@ -165,52 +142,24 @@ impl<'a> Traverse<'a> for Transformer<'a> {
165142
instruction.identifier
166143
));
167144

168-
body.statements.insert(
169-
0,
170-
parse_js_code_to_statements(self.allocator, &source_text, SourceType::mjs())
171-
.into_iter()
172-
.next()
173-
.unwrap(),
174-
);
175-
}
176-
}
177-
178-
/*fn exit_method_definition(
179-
&mut self,
180-
_node: &mut MethodDefinition<'a>,
181-
ctx: &mut TraverseCtx<'a>,
182-
) {
183-
if self.current_function_identifier.is_none() {
184-
return;
185-
}
186-
187-
// If we are in a sub function, we need to decrease the counter
188-
// If we leave the last sub function, we need to modify the return value again
189-
if self.sub_function_counter > 0 {
190-
self.sub_function_counter -= 1;
191-
192-
if self.sub_function_counter == 0 {
193-
self.modify_return_value = true;
194-
}
195-
196-
return;
145+
insert_single_statement_into_func(self.allocator, body, 0, source_text);
197146
}
198147

199-
// We leave the current function we want to instrument
200-
self.modify_return_value = false;
201-
self.current_function_identifier = None;
148+
// Todo support return value modification
202149
}
150+
}
203151

204-
fn enter_return_statement(
205-
&mut self,
206-
node: &mut oxc_ast::ast::ReturnStatement<'a>,
207-
ctx: &mut TraverseCtx<'a>,
208-
) {
209-
if !self.modify_return_value {
210-
return;
211-
}
212-
213-
// Todo support modifying return value
214-
//AstBuilder::new(self.allocator).return_statement(node.span, argument)
215-
}*/
152+
fn insert_single_statement_into_func<'a>(
153+
allocator: &'a Allocator,
154+
body: &mut Box<'a, FunctionBody<'a>>,
155+
pos: usize,
156+
source_text: &'a str,
157+
) {
158+
body.statements.insert(
159+
pos,
160+
parse_js_code_to_statements(&allocator, &source_text, SourceType::mjs())
161+
.into_iter()
162+
.next()
163+
.unwrap(),
164+
);
216165
}

library/agent/hooks/instrumentation/types.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,17 @@ export type IntereptorFunctionsObj = {
5959
modifyReturnValue?: ModifyReturnValueInterceptor;
6060
};
6161

62+
export type PackageFunctionInstrumentationInstruction = {
63+
nodeType: "MethodDefinition";
64+
name: string;
65+
inspectArgs?: InspectArgsInterceptor;
66+
modifyArgs?: ModifyArgsInterceptor;
67+
modifyReturnValue?: ModifyReturnValueInterceptor;
68+
};
69+
6270
export type PackageFileInstrumentationInstruction = {
6371
path: string; // Relative path to required file inside the package folder
64-
functions: {
65-
nodeType: "MethodDefinition";
66-
name: string;
67-
inspectArgs?: InspectArgsInterceptor;
68-
modifyArgs?: ModifyArgsInterceptor;
69-
modifyReturnValue?: ModifyReturnValueInterceptor;
70-
}[];
72+
functions: PackageFunctionInstrumentationInstruction[];
7173
};
7274

7375
export type PackageFileInstrumentationInstructionJSON = {

library/sinks/Postgres.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ export class Postgres implements Wrapper {
5656
wrapExport(exports.Client.prototype, "query", pkgInfo, {
5757
inspectArgs: (args) => this.inspectQuery(args),
5858
});
59+
})
60+
.addFileInstrumentation({
61+
path: "lib/client.js",
62+
functions: [
63+
{
64+
nodeType: "MethodDefinition",
65+
name: "query",
66+
inspectArgs: (args) => this.inspectQuery(args),
67+
},
68+
],
5969
});
6070
}
6171
}

library/sources/Hono.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Wrapper } from "../agent/Wrapper";
55
import { wrapRequestHandler } from "./hono/wrapRequestHandler";
66
import { wrapExport } from "../agent/hooks/wrapExport";
77
import { wrapNewInstance } from "../agent/hooks/wrapNewInstance";
8+
import type { PackageFunctionInstrumentationInstruction } from "../agent/hooks/instrumentation/types";
89

910
const METHODS = [
1011
"get",
@@ -38,6 +39,17 @@ export class Hono implements Wrapper {
3839
}
3940

4041
wrap(hooks: Hooks) {
42+
// Instrumentation instructions for the new system
43+
const functionsToInstrument: PackageFunctionInstrumentationInstruction[] = [
44+
{
45+
nodeType: "MethodDefinition",
46+
name: "addRoute",
47+
modifyArgs: (args) => {
48+
return this.wrapArgs(args);
49+
},
50+
},
51+
];
52+
4153
hooks
4254
.addPackage("hono")
4355
.withVersion("^4.0.0")
@@ -56,15 +68,11 @@ export class Hono implements Wrapper {
5668
})
5769
.addFileInstrumentation({
5870
path: "dist/hono-base.js", //CJS has a different path
59-
functions: [
60-
{
61-
nodeType: "MethodDefinition",
62-
name: "addRoute",
63-
modifyArgs: (args) => {
64-
return this.wrapArgs(args);
65-
},
66-
},
67-
],
71+
functions: functionsToInstrument,
72+
})
73+
.addFileInstrumentation({
74+
path: "dist/cjs/hono-base.js",
75+
functions: functionsToInstrument,
6876
});
6977
}
7078
}

sample-apps/hono-esm/app.js

Lines changed: 0 additions & 17 deletions
This file was deleted.

sample-apps/hono-esm/package-lock.json

Lines changed: 0 additions & 48 deletions
This file was deleted.

sample-apps/hono-pg-esm/app.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { Hono } from "hono";
2+
import { serve } from "@hono/node-server";
3+
import { readFile } from "fs/promises";
4+
import { join } from "path";
5+
import { createConnection } from "./db.js";
6+
7+
const app = new Hono();
8+
const db = await createConnection();
9+
10+
app.get("/", async (c) => {
11+
return c.text("Hello, World!");
12+
});
13+
14+
app.get("/file", async (c) => {
15+
const path = c.req.query("path");
16+
const data = await readFile(
17+
join(import.meta.dirname, "files", path || "test.txt"),
18+
"utf8"
19+
);
20+
return c.text(data);
21+
});
22+
23+
app.get("/clear", async (c) => {
24+
await db.query("DELETE FROM cats_3;");
25+
return c.text("Table cleared");
26+
});
27+
28+
function getPort() {
29+
const port = parseInt(process.argv[2], 10) || 4000;
30+
31+
if (isNaN(port)) {
32+
console.error("Invalid port");
33+
process.exit(1);
34+
}
35+
36+
return port;
37+
}
38+
39+
serve(
40+
{
41+
fetch: app.fetch,
42+
port: getPort(),
43+
},
44+
(info) => {
45+
console.log(`Server is running on http://${info.address}:${info.port}`);
46+
}
47+
);

sample-apps/hono-pg-esm/db.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pg from "pg";
2+
const { Client } = pg;
3+
4+
export async function createConnection() {
5+
const client = new Client({
6+
user: "root",
7+
host: "127.0.0.1",
8+
database: "main_db",
9+
password: "password",
10+
port: 27016,
11+
});
12+
13+
await client.connect();
14+
await client.query(`
15+
CREATE TABLE IF NOT EXISTS cats_3 (
16+
petname varchar(255),
17+
comment varchar(255)
18+
);
19+
`);
20+
21+
return client;
22+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hi

0 commit comments

Comments
 (0)