11import { ExecutionContext } from 'ava' ;
2- import { Runtime } from '@temporalio/worker' ;
2+ import { ActivityInboundCallsInterceptor , ActivityOutboundCallsInterceptor , Runtime } from '@temporalio/worker' ;
33import * as workflow from '@temporalio/workflow' ;
4+ import { MetricTags } from '@temporalio/common' ;
5+ import { Context as ActivityContext , metricMeter as activityMetricMeter } from '@temporalio/activity' ;
46import { Context as BaseContext , helpers , makeTestFunction } from './helpers-integration' ;
57import { getRandomPort } from './helpers' ;
68
@@ -261,7 +263,7 @@ export async function MetricTagsWorkflow(): Promise<void> {
261263
262264test ( 'Metric tags in Workflow works' , async ( t ) => {
263265 const { createWorker, executeWorkflow, taskQueue } = helpers ( t ) ;
264- const tags = `labelA="value-a",labelB="value-b2",labelC="value-c",labelD="value-d",labelX="value-x",labelY="value-y",namespace="default",taskQueue="${ taskQueue } "` ;
266+ const tags = `labelA="value-a",labelB="value-b2",labelC="value-c",labelD="value-d",labelX="value-x",labelY="value-y",namespace="default",taskQueue="${ taskQueue } ",workflowType="MetricTagsWorkflow" ` ;
265267
266268 const worker = await createWorker ( ) ;
267269 await worker . runUntil ( executeWorkflow ( MetricTagsWorkflow ) ) ;
@@ -270,3 +272,103 @@ test('Metric tags in Workflow works', async (t) => {
270272 await assertMetricReported ( t , new RegExp ( `workflow2_histogram_bucket{${ tags } ,le="50"} 1` ) ) ;
271273 await assertMetricReported ( t , new RegExp ( `workflow2_gauge{${ tags } } 2` ) ) ;
272274} ) ;
275+
276+ // Define workflow interceptor for metrics
277+ export const interceptors = ( ) : workflow . WorkflowInterceptors => ( {
278+ outbound : [
279+ {
280+ getMetricTags ( tags : MetricTags ) : MetricTags {
281+ if ( ! workflow . workflowInfo ( ) . workflowType . includes ( 'Interceptor' ) ) return tags ;
282+ return {
283+ ...tags ,
284+ intercepted : 'workflow-interceptor' ,
285+ } ;
286+ } ,
287+ } ,
288+ ] ,
289+ } ) ;
290+
291+ // Define activity interceptor for metrics
292+ export function activityInterceptorFactory ( _ctx : ActivityContext ) : {
293+ inbound ?: ActivityInboundCallsInterceptor ;
294+ outbound ?: ActivityOutboundCallsInterceptor ;
295+ } {
296+ return {
297+ outbound : {
298+ getMetricTags ( tags : MetricTags ) : MetricTags {
299+ return {
300+ ...tags ,
301+ intercepted : 'activity-interceptor' ,
302+ } ;
303+ } ,
304+ } ,
305+ } ;
306+ }
307+
308+ // Activity that uses metrics
309+ export async function metricActivity ( ) : Promise < void > {
310+ const { metricMeter } = ActivityContext . current ( ) ;
311+
312+ const counter = metricMeter . createCounter ( 'activity-counter' ) ;
313+ counter . add ( 5 ) ;
314+
315+ const histogram = metricMeter . createHistogram ( 'activity-histogram' ) ;
316+ histogram . record ( 10 ) ;
317+
318+ // Use the `metricMeter` exported from the top level of the activity module rather than the one in the context
319+ const gauge = activityMetricMeter . createGauge ( 'activity-gauge' ) ;
320+ gauge . set ( 15 ) ;
321+ }
322+
323+ // Workflow that uses metrics and calls the activity
324+ export async function metricsInterceptorWorkflow ( ) : Promise < void > {
325+ const metricMeter = workflow . metricMeter ;
326+
327+ // Use workflow metrics
328+ const counter = metricMeter . createCounter ( 'intercepted-workflow-counter' ) ;
329+ counter . add ( 3 ) ;
330+
331+ const histogram = metricMeter . createHistogram ( 'intercepted-workflow-histogram' ) ;
332+ histogram . record ( 6 ) ;
333+
334+ const gauge = metricMeter . createGauge ( 'intercepted-workflow-gauge' ) ;
335+ gauge . set ( 9 ) ;
336+
337+ // Call activity with metrics
338+ await workflow
339+ . proxyActivities ( {
340+ startToCloseTimeout : '1 minute' ,
341+ } )
342+ . metricActivity ( ) ;
343+ }
344+
345+ // Test for workflow metrics interceptor
346+ test ( 'Workflow and Activity Context metrics interceptors add tags' , async ( t ) => {
347+ const { createWorker, executeWorkflow, taskQueue } = helpers ( t ) ;
348+
349+ const worker = await createWorker ( {
350+ taskQueue,
351+ workflowsPath : __filename ,
352+ activities : {
353+ metricActivity,
354+ } ,
355+ interceptors : {
356+ activity : [ activityInterceptorFactory ] ,
357+ } ,
358+ } ) ;
359+
360+ await worker . runUntil ( executeWorkflow ( metricsInterceptorWorkflow ) ) ;
361+
362+ // Verify workflow metrics have interceptor tag
363+ await assertMetricReported ( t , / i n t e r c e p t e d _ w o r k f l o w _ c o u n t e r { [ ^ } ] * i n t e r c e p t e d = " w o r k f l o w - i n t e r c e p t o r " [ ^ } ] * } 3 / ) ;
364+ await assertMetricReported (
365+ t ,
366+ / i n t e r c e p t e d _ w o r k f l o w _ h i s t o g r a m _ b u c k e t { [ ^ } ] * i n t e r c e p t e d = " w o r k f l o w - i n t e r c e p t o r " [ ^ } ] * } \d + /
367+ ) ;
368+ await assertMetricReported ( t , / i n t e r c e p t e d _ w o r k f l o w _ g a u g e { [ ^ } ] * i n t e r c e p t e d = " w o r k f l o w - i n t e r c e p t o r " [ ^ } ] * } 9 / ) ;
369+
370+ // Verify activity metrics have interceptor tag
371+ await assertMetricReported ( t , / a c t i v i t y _ c o u n t e r { [ ^ } ] * i n t e r c e p t e d = " a c t i v i t y - i n t e r c e p t o r " [ ^ } ] * } 5 / ) ;
372+ await assertMetricReported ( t , / a c t i v i t y _ h i s t o g r a m _ b u c k e t { [ ^ } ] * i n t e r c e p t e d = " a c t i v i t y - i n t e r c e p t o r " [ ^ } ] * } \d + / ) ;
373+ await assertMetricReported ( t , / a c t i v i t y _ g a u g e { [ ^ } ] * i n t e r c e p t e d = " a c t i v i t y - i n t e r c e p t o r " [ ^ } ] * } 1 5 / ) ;
374+ } ) ;
0 commit comments