JavaScript์—์„œ ์ถ”์  ์ด๋ฒคํŠธ ๋‚ด๋ณด๋‚ด๊ธฐยถ

Snowflake JavaScript API ์˜ snowflake ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JavaScript๋กœ ์ž‘์„ฑ๋œ ํ•จ์ˆ˜ ๋˜๋Š” ํ”„๋กœ์‹œ์ € ์ฒ˜๋ฆฌ๊ธฐ์—์„œ ์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JavaScript API๋Š” JavaScript ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์—์„œ ์ด๋ฏธ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ๋‚ด๋ณด๋‚ด๊ธฐ ์ „์— ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์— ์ €์žฅ๋˜๋„๋ก ์ถ”์  ์ˆ˜์ค€์„ ์„ค์ •ํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋กœ๊น…, ๋ฉ”ํŠธ๋ฆญ ๋ฐ ์ถ”์ ์„ ์œ„ํ•œ ์ˆ˜์ค€ ์„ค์ •ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ฐธ๊ณ 

์ถ”์  ์ด๋ฒคํŠธ ๋‚ด๋ณด๋‚ด๊ธฐ๋ฅผ ์‹œ์ž‘ํ•˜๋ ค๋ฉด ๋จผ์ € ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์„ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ” ๊ฐœ์š” ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์—์„œ SELECT ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ์ €์žฅ๋œ ์ถ”์  ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ถ”์  ๋ฐ์ดํ„ฐ ๋ณด๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Snowflake์—์„œ ๋กœ๊น… ์„ค์ • ๋ฐ ๋ฉ”์‹œ์ง€ ๊ฒ€์ƒ‰์— ๋Œ€ํ•œ ์ผ๋ฐ˜์ ์ธ ์ •๋ณด๋Š” ํ•จ์ˆ˜์™€ ํ”„๋กœ์‹œ์ €์˜ ์ถ”์  ์ด๋ฒคํŠธ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ฐธ๊ณ 

์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์—ผ๋‘์— ๋‘์–ด์•ผ ํ•  ์ง€์นจ์€ ์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ผ๋ฐ˜ ์ง€์นจ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ถ”์  ์ด๋ฒคํŠธ ์ถ”๊ฐ€ํ•˜๊ธฐยถ

snowflake.addEvent ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ด๋ฒคํŠธ ์ด๋ฆ„์„ ์ „๋‹ฌํ•˜์—ฌ ์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ ํŠน์„ฑ(ํ‚ค-๊ฐ’ ํŽ˜์–ด)์„ ์ด๋ฒคํŠธ์™€ ์—ฐ๊ฒฐํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

addEvent ๋ฉ”์„œ๋“œ๋Š” ๋‹ค์Œ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

snowflake.addEvent(name [, { key:value [, key:value] } ] );
Copy

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฒ˜๋ฆฌ๊ธฐ ์ฝ”๋“œ์—์„œ๋Š” name_a ์™€ name_b ์˜ ๋‘ ์ด๋ฒคํŠธ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ์—์„œ name_b ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด score ์™€ pass ์˜ ๋‘ ๊ฐ€์ง€ ํŠน์„ฑ๋„ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.

create procedure PI_JS()
  returns double
  language javascript
  as
  $$
    snowflake.addEvent('name_a');  // add an event without attributes
    snowflake.addEvent('name_b', {'score': 89, 'pass': true});
    return 3.14;
  $$
  ;
Copy

์ด๋Ÿฌํ•œ ํŠน์„ฑ์„ ์„ค์ •ํ•˜๋ฉด ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์— ๋‘ ๊ฐœ์˜ ํ–‰์ด ์ƒ๊ธฐ๋Š”๋ฐ, RECORD ์—ด์˜ ๊ฐ’์ด ๊ฐ๊ฐ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

{
  "name": "name_a"
}
Copy
{
  "name": "name_b"
}
Copy

name_b ์ด๋ฒคํŠธ ํ–‰์˜ RECORD_ATTRIBUTES ์—ด์— ๋‹ค์Œ ํŠน์„ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

{
  "score": 89,
  "pass": true
}
Copy

๋ฒ”์œ„ ํŠน์„ฑ ์ถ”๊ฐ€ํ•˜๊ธฐยถ

snowflake.setSpanAttribute ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ฒ”์œ„์™€ ์—ฐ๊ฒฐ๋œ ํŠน์„ฑ(ํ‚ค-๊ฐ’ ํŽ˜์–ด)์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

setSpanAttribute ํ•จ์ˆ˜๋Š” ๋‹ค์Œ ํ˜•์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

snowflake.setSpanAttribute(key, value);
Copy

๋ฒ”์œ„์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Snowflake๊ฐ€ ์ถ”์  ์ด๋ฒคํŠธ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ• ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” 4๊ฐ€์ง€ ํŠน์„ฑ์„ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

// Setting span attributes.
snowflake.setSpanAttribute("example.boolean", true);
snowflake.setSpanAttribute("example.long", 2L);
snowflake.setSpanAttribute("example.double", 2.5);
snowflake.setSpanAttribute("example.string", "testAttribute");
Copy

์ด๋Ÿฌํ•œ ํŠน์„ฑ์„ ์„ค์ •ํ•˜๋ฉด ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์˜ RECORD_ATTRIBUTES ์—ด์— ๋‹ค์Œ ๋‚ด์šฉ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

{
  "example.boolean": true,
  "example.long": 2,
  "example.double": 2.5,
  "example.string": "testAttribute"
}
Copy

์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ”์œ„ ์ถ”๊ฐ€ํ•˜๊ธฐยถ

Snowflake์—์„œ ์ƒ์„ฑ๋œ ๊ธฐ๋ณธ ๋ฒ”์œ„์™€ ๋ณ„๋„๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ”์œ„๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ”์œ„์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ถ”์ ์— ์‚ฌ์šฉ์ž ์ง€์ • ๋ฒ”์œ„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์„น์…˜์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‹ค์Œ ์˜ˆ์ œ์˜ ์ฝ”๋“œ๋Š” OpenTelemetry API ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ example_custom_span ๋ฒ”์œ„๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๋ฒคํŠธ์™€ ํŠน์„ฑ์„ ์ƒˆ ๋ฒ”์œ„์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ์ด ์ฝ”๋“œ๋Š” ๋ฒ”์œ„๋ฅผ ์ข…๋ฃŒํ•˜์—ฌ ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์— ํ•ด๋‹น ๋ฒ”์œ„์˜ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ์บก์ฒ˜๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ์—์„œ Span.end ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฒคํŠธ ํ…Œ์ด๋ธ”์— ๋ฐ์ดํ„ฐ๊ฐ€ ์บก์ฒ˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

CREATE OR REPLACE FUNCTION javascript_custom_span()
RETURNS STRING
LANGUAGE JAVASCRIPT
AS
$$
const { trace } = opentelemetry;
const tracer = trace.getTracer("example_tracer");
// Alternatively, const tracer = opentelemetry.trace.getTracer("example_tracer");

tracer.startActiveSpan("example_custom_span", (span) => {
  span.addEvent("testEventWithAttributes");
  span.setAttribute("testAttribute", "value");

  span.end();
});
$$;
Copy