12
12
import io .airbyte .commons .lang .Exceptions .Procedure ;
13
13
import io .airbyte .commons .string .Strings ;
14
14
import io .airbyte .commons .util .AutoCloseableIterator ;
15
+ import io .airbyte .commons .version .AirbyteVersion ;
16
+ import io .airbyte .config .Configs .WorkerEnvironment ;
17
+ import io .airbyte .config .EnvConfigs ;
18
+ import io .airbyte .config .WorkerEnvConstants ;
15
19
import io .airbyte .integrations .base .sentry .AirbyteSentry ;
16
20
import io .airbyte .protocol .models .AirbyteConnectionStatus ;
17
21
import io .airbyte .protocol .models .AirbyteMessage ;
18
22
import io .airbyte .protocol .models .AirbyteMessage .Type ;
19
23
import io .airbyte .protocol .models .ConfiguredAirbyteCatalog ;
20
24
import io .airbyte .validation .json .JsonSchemaValidator ;
21
25
import io .sentry .ITransaction ;
26
+ import io .sentry .NoOpTransaction ;
22
27
import io .sentry .Sentry ;
23
28
import io .sentry .SentryLevel ;
24
29
import io .sentry .SpanStatus ;
@@ -93,16 +98,10 @@ public IntegrationRunner(final Source source) {
93
98
}
94
99
95
100
public void run (final String [] args ) throws Exception {
96
- initSentry ();
97
-
98
101
final IntegrationConfig parsed = cliParser .parse (args );
99
- final ITransaction transaction = Sentry .startTransaction (
100
- integration .getClass ().getSimpleName (),
101
- parsed .getCommand ().toString (),
102
- true );
103
- LOGGER .info ("Sentry transaction event: {}" , transaction .getEventId ());
102
+ final ITransaction transaction = createSentryTransaction (integration .getClass (), parsed .getCommand ());
104
103
try {
105
- runInternal (transaction , parsed );
104
+ runInternal (parsed );
106
105
transaction .finish (SpanStatus .OK );
107
106
} catch (final Exception e ) {
108
107
transaction .setThrowable (e );
@@ -117,7 +116,7 @@ public void run(final String[] args) throws Exception {
117
116
}
118
117
}
119
118
120
- public void runInternal (final ITransaction transaction , final IntegrationConfig parsed ) throws Exception {
119
+ private void runInternal (final IntegrationConfig parsed ) throws Exception {
121
120
LOGGER .info ("Running integration: {}" , integration .getClass ().getName ());
122
121
LOGGER .info ("Command: {}" , parsed .getCommand ());
123
122
LOGGER .info ("Integration config: {}" , parsed );
@@ -285,21 +284,76 @@ private static <T> T parseConfig(final Path path, final Class<T> klass) {
285
284
return Jsons .object (jsonNode , klass );
286
285
}
287
286
288
- private static void initSentry () {
287
+ private static ITransaction createSentryTransaction (final Class <?> connectorClass , final Command command ) {
288
+ if (command == Command .SPEC ) {
289
+ return NoOpTransaction .getInstance ();
290
+ }
291
+
289
292
final Map <String , String > env = System .getenv ();
290
- final String connector = env .getOrDefault ("APPLICATION" , "unknown" );
291
- final String version = env .getOrDefault ("APPLICATION_VERSION" , "unknown" );
292
293
final boolean enableSentry = Boolean .parseBoolean (env .getOrDefault ("ENABLE_SENTRY" , "false" ));
294
+ final String sentryDsn = env .getOrDefault ("SENTRY_DSN" , "" );
295
+ if (!enableSentry || sentryDsn .equals ("" )) {
296
+ LOGGER .debug ("Skip Sentry transaction because DSN is not available" );
297
+ return NoOpTransaction .getInstance ();
298
+ }
299
+
300
+ final String version = parseConnectorVersion (env .getOrDefault ("WORKER_CONNECTOR_IMAGE" , "" ));
301
+ final String airbyteVersion = env .getOrDefault (EnvConfigs .AIRBYTE_VERSION , "" );
302
+ final String airbyteRole = env .getOrDefault (EnvConfigs .AIRBYTE_ROLE , "" );
303
+ final boolean isDev = version .equals (AirbyteVersion .DEV_VERSION )
304
+ || airbyteVersion .equals (AirbyteVersion .DEV_VERSION )
305
+ || airbyteRole .equals ("airbyter" );
306
+ if (isDev ) {
307
+ LOGGER .debug ("Skip Sentry transaction for dev environment" );
308
+ return NoOpTransaction .getInstance ();
309
+ }
310
+ final String connector = env .getOrDefault ("APPLICATION" , "" );
311
+ if (connector .equals ("" )) {
312
+ LOGGER .debug ("Skip Sentry transaction for unknown connector" );
313
+ return NoOpTransaction .getInstance ();
314
+ }
315
+ final String workerEnvironment = env .getOrDefault ("WORKER_ENVIRONMENT" , "" );
316
+ final String workerJobId = env .getOrDefault (WorkerEnvConstants .WORKER_JOB_ID , "" );
317
+ final String workerJobAttempt = env .getOrDefault (WorkerEnvConstants .WORKER_JOB_ATTEMPT , "" );
318
+ if (workerEnvironment .equals ("" ) || workerEnvironment .equals (WorkerEnvironment .DOCKER .name ())) {
319
+ LOGGER .debug ("Skip Sentry transaction for unknown or docker deployment" );
320
+ return NoOpTransaction .getInstance ();
321
+ }
293
322
294
323
// https://docs.sentry.io/platforms/java/configuration/
295
324
Sentry .init (options -> {
296
- options .setDsn (enableSentry ? env . getOrDefault ( "SENTRY_DSN" , "" ) : "" );
325
+ options .setDsn (sentryDsn );
297
326
options .setEnableExternalConfiguration (true );
298
- options .setTracesSampleRate (enableSentry ? 1.0 : 0 .0 );
327
+ options .setTracesSampleRate (1 .0 );
299
328
options .setRelease (String .format ("%s@%s" , connector , version ));
329
+ options .setEnvironment (isDev ? "dev" : "production" );
300
330
options .setTag ("connector" , connector );
301
331
options .setTag ("connector_version" , version );
332
+ options .setTag ("job_id" , workerJobId );
333
+ options .setTag ("job_attempt" , workerJobAttempt );
334
+ options .setTag ("airbyte_version" , airbyteVersion );
335
+ options .setTag ("worker_environment" , workerEnvironment );
302
336
});
337
+
338
+ final ITransaction transaction = Sentry .startTransaction (
339
+ connectorClass .getSimpleName (),
340
+ command .toString (),
341
+ true );
342
+ LOGGER .info ("Sentry transaction event: {}" , transaction .getEventId ());
343
+ return transaction ;
344
+ }
345
+
346
+ /**
347
+ * @param connectorImage Expected format: [organization/]image[:version]
348
+ */
349
+ @ VisibleForTesting
350
+ static String parseConnectorVersion (final String connectorImage ) {
351
+ if (connectorImage == null || connectorImage .equals ("" )) {
352
+ return "unknown" ;
353
+ }
354
+
355
+ final String [] tokens = connectorImage .split (":" );
356
+ return tokens [tokens .length - 1 ];
303
357
}
304
358
305
359
}
0 commit comments