@@ -9,6 +9,7 @@ import { HqlError, HqlErrorCode, hqlError, parseClickhouseError } from "../lib/e
99import { AST , Parser } from "node-sql-parser" ;
1010import { HqlStore } from "../lib/stores/HqlStore" ;
1111import { z } from "zod" ;
12+ import tracer from "../tracer" ;
1213
1314export const CLICKHOUSE_TABLES = [ "request_response_rmt" ] ;
1415const MAX_LIMIT = 300000 ;
@@ -119,7 +120,10 @@ export class HeliconeSqlManager {
119120 async getClickhouseSchema ( ) : Promise <
120121 Result < ClickHouseTableSchema [ ] , HqlError >
121122 > {
123+ const span = tracer . startSpan ( "hql.getClickhouseSchema" ) ;
122124 try {
125+ span . setTag ( "resource.name" , "hql.getClickhouseSchema" ) ;
126+ span . setTag ( "span.type" , "custom" ) ;
123127 const schemaPromises = CLICKHOUSE_TABLES . map ( async ( table_name ) => {
124128 const columns = await clickhouseDb . dbQuery < ClickHouseTableRow > (
125129 `DESCRIBE TABLE ${ table_name } ` ,
@@ -149,13 +153,18 @@ export class HeliconeSqlManager {
149153 } ) ;
150154
151155 const schema = await Promise . all ( schemaPromises ) ;
156+ span . setTag ( "hql.table_count" , schema . length ) ;
152157 return ok ( schema ) ;
153158 } catch ( e ) {
154159 const errorMessage = e instanceof Error ? e . message : String ( e ) ;
160+ span . setTag ( "error" , true ) ;
161+ span . setTag ( "error.message" , errorMessage ) ;
155162 return hqlError (
156163 HqlErrorCode . SCHEMA_FETCH_FAILED ,
157164 errorMessage
158165 ) ;
166+ } finally {
167+ span . finish ( ) ;
159168 }
160169 }
161170
@@ -167,12 +176,21 @@ export class HeliconeSqlManager {
167176 sql : string ,
168177 limit : number = 100
169178 ) : Promise < Result < ExecuteSqlResponse , HqlError > > {
179+ const span = tracer . startSpan ( "hql.executeSql" ) ;
180+ span . setTag ( "resource.name" , "hql.executeSql" ) ;
181+ span . setTag ( "span.type" , "custom" ) ;
182+ span . setTag ( "hql.limit" , limit ) ;
170183 try {
171184 // Parse SQL to validate and add limit
172185 let ast ;
173186 try {
174187 ast = parser . astify ( sql , { database : "Postgresql" } ) ;
175188 } catch ( parseError ) {
189+ span . setTag ( "error" , true ) ;
190+ span . setTag (
191+ "error.message" ,
192+ parseError instanceof Error ? parseError . message : String ( parseError )
193+ ) ;
176194 return hqlError (
177195 HqlErrorCode . SYNTAX_ERROR ,
178196 parseError instanceof Error ? parseError . message : String ( parseError )
@@ -187,6 +205,11 @@ export class HeliconeSqlManager {
187205 try {
188206 limitedAst = addLimit ( normalizedAst , limit ) ;
189207 } catch ( limitError ) {
208+ span . setTag ( "error" , true ) ;
209+ span . setTag (
210+ "error.message" ,
211+ limitError instanceof Error ? limitError . message : String ( limitError )
212+ ) ;
190213 return hqlError (
191214 HqlErrorCode . SYNTAX_ERROR ,
192215 `Failed to apply limit: ${ limitError instanceof Error ? limitError . message : String ( limitError ) } `
@@ -198,6 +221,8 @@ export class HeliconeSqlManager {
198221 // Validate SQL for security
199222 const validatedSql = validateSql ( firstSql ) ;
200223 if ( isError ( validatedSql ) ) {
224+ span . setTag ( "error" , true ) ;
225+ span . setTag ( "error.message" , validatedSql . error . message ) ;
201226 return validatedSql ;
202227 }
203228
@@ -211,34 +236,53 @@ export class HeliconeSqlManager {
211236 } ) ;
212237
213238 const elapsedMilliseconds = Date . now ( ) - start ;
239+ span . setTag ( "hql.elapsed_ms" , elapsedMilliseconds ) ;
240+ span . setTag ( "hql.organization_id" , this . authParams . organizationId ) ;
214241
215242 if ( isError ( result ) ) {
216243 const errorCode = parseClickhouseError ( result . error ) ;
244+ span . setTag ( "error" , true ) ;
245+ span . setTag ( "error.message" , result . error ) ;
246+ span . setTag ( "hql.error_code" , errorCode ) ;
217247 return hqlError ( errorCode , result . error ) ;
218248 }
219249
250+ const rows = result . data ?? [ ] ;
251+ const size = Buffer . byteLength ( JSON . stringify ( rows ) , "utf8" ) ;
252+ span . setTag ( "hql.row_count" , rows . length ) ;
253+ span . setTag ( "hql.size_bytes" , size ) ;
220254 return ok ( {
221255 rows : result . data ?? [ ] ,
222256 elapsedMilliseconds,
223- size : Buffer . byteLength ( JSON . stringify ( result . data ) , "utf8" ) ,
224- rowCount : result . data ?. length ?? 0 ,
257+ size,
258+ rowCount : rows . length ,
225259 } ) ;
226260 } catch ( e ) {
227261 const errorMessage = e instanceof Error ? e . message : String ( e ) ;
262+ span . setTag ( "error" , true ) ;
263+ span . setTag ( "error.message" , errorMessage ) ;
228264 return hqlError (
229265 HqlErrorCode . UNEXPECTED_ERROR ,
230266 errorMessage
231267 ) ;
268+ } finally {
269+ span . finish ( ) ;
232270 }
233271 }
234272
235273 async downloadCsv ( sql : string ) : Promise < Result < string , HqlError > > {
274+ const span = tracer . startSpan ( "hql.downloadCsv" ) ;
275+ span . setTag ( "resource.name" , "hql.downloadCsv" ) ;
276+ span . setTag ( "span.type" , "custom" ) ;
236277 const result = await this . executeSql ( sql , MAX_LIMIT ) ;
237278 if ( isError ( result ) ) {
279+ span . setTag ( "error" , true ) ;
280+ span . setTag ( "error.message" , result . error . message ) ;
238281 return result ;
239282 }
240283
241284 if ( ! result . data ?. rows ?. length ) {
285+ span . setTag ( "hql.no_data" , true ) ;
242286 return hqlError ( HqlErrorCode . NO_DATA_RETURNED ) ;
243287 }
244288
@@ -254,16 +298,21 @@ export class HeliconeSqlManager {
254298 ) ;
255299
256300 if ( isError ( uploadResult ) ) {
301+ span . setTag ( "error" , true ) ;
302+ span . setTag ( "error.message" , uploadResult . error ) ;
257303 return hqlError (
258304 HqlErrorCode . CSV_UPLOAD_FAILED ,
259305 uploadResult . error
260306 ) ;
261307 }
262308
263309 if ( ! uploadResult . data ) {
310+ span . setTag ( "error" , true ) ;
311+ span . setTag ( "error.message" , "CSV URL not returned" ) ;
264312 return hqlError ( HqlErrorCode . CSV_URL_NOT_RETURNED ) ;
265313 }
266314
315+ span . setTag ( "hql.csv_url_generated" , true ) ;
267316 return ok ( uploadResult . data ) ;
268317 }
269318}
0 commit comments