public static SimpleSignalFlowProgramBuilder create(String metricName, String aggregationMethod, SignalFxScopeConfiguration scopeConfiguration) { return new SimpleSignalFlowProgramBuilder(metricName, aggregationMethod, scopeConfiguration); }
@Override public String buildQuery(String metricsAccountName, CanaryConfig canaryConfig, CanaryMetricConfig canaryMetricConfig, CanaryScope canaryScope) { SignalFxScopeConfiguration scopeConfiguration = signalFxScopeConfigurationMap.get(metricsAccountName); SignalFxCanaryScope signalFxCanaryScope = (SignalFxCanaryScope) canaryScope; SignalFxCanaryMetricSetQueryConfig queryConfig = (SignalFxCanaryMetricSetQueryConfig) canaryMetricConfig.getQuery(); String aggregationMethod = Optional.ofNullable(queryConfig.getAggregationMethod()).orElse("mean"); List<QueryPair> queryPairs = Optional.ofNullable(queryConfig.getQueryPairs()).orElse(new LinkedList<>()); return SimpleSignalFlowProgramBuilder .create(queryConfig.getMetricName(), aggregationMethod, scopeConfiguration) .withQueryPairs(queryPairs) .withScope(signalFxCanaryScope) .build(); }
public SimpleSignalFlowProgramBuilder withScope(SignalFxCanaryScope canaryScope) { scopeKeys.addAll(Optional.ofNullable(canaryScope.getExtendedScopeParams()).orElse(new HashMap<>()) .keySet().stream().filter(key -> !key.startsWith("_")).collect(Collectors.toList())); canaryScope.setScopeKey(Optional.ofNullable(canaryScope.getScopeKey()) .orElseGet(() -> Optional.ofNullable(scopeConfiguration.getDefaultScopeKey()) .orElseThrow(() -> new IllegalArgumentException("The SignalFx account must define a default scope key or " + "it must be supplied in the extendedScopeParams in the `_scope_key` key")))); Optional.ofNullable(Optional.ofNullable(canaryScope.getLocationKey()) .orElse(Optional.ofNullable(scopeConfiguration.getDefaultLocationKey()).orElse(null))) .ifPresent( locationKey -> { canaryScope.setLocationKey(locationKey); scopeKeys.add(locationKey); }); scopeKeys.add(canaryScope.getScopeKey()); filterSegments.add(buildFilterSegmentFromScope(canaryScope)); return this; }
@Test @UseDataProvider("locationScopeProvider") public void test_that_the_program_builder_builds_the_expected_program_when_location_is_provided( SignalFxCanaryScope scope, SignalFxScopeConfiguration scopeConfiguration) { String metricName = "request.count"; String aggregationMethod = "mean"; SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withQueryPair(new QueryPair("app", "cms")); builder.withQueryPair(new QueryPair("response_code", "400")); builder.withQueryPair(new QueryPair("uri", "/v2/auth/iam-principal")); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('app', 'cms') " + "and filter('response_code', '400') " + "and filter('uri', '/v2/auth/iam-principal') " + "and filter('version', '1.0.0') " + "and filter('region', 'us-west-2') " + "and filter('env', 'production'))" + ".mean(by=['env', 'region', 'version']).publish()"; assertEquals(expected, builder.build()); }
@Test public void test_that_when_there_are_extra_scope_query_pairs_that_the_program_builds_as_expected() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = new SignalFxScopeConfiguration(); scope.setScope("1.0.0"); scope.setScopeKey("version"); scope.setExtendedScopeParams(ImmutableMap.of("_scope_key", "version")); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('version', '1.0.0'))" + ".mean(by=['version']).publish()"; assertEquals(expected, builder.build()); }
AccountCredentialsRepository accountCredentialsRepository) { SignalFxMetricsService.SignalFxMetricsServiceBuilder metricsServiceBuilder = SignalFxMetricsService.builder(); metricsServiceBuilder.accountName(name); .map(SignalFxManagedAccount::getName).collect(Collectors.toList()))); return metricsServiceBuilder.build();
String program = buildQuery(metricsAccountName, canaryConfig, canaryMetricConfig, canaryScope); .endTimeIso(Instant.ofEpochMilli(endEpochMilli).toString()) .stepMillis(stepMilli) .values(getTimeSeriesDataFromChannelMessages(signalFlowExecutionResult.getChannelMessages())) .tags(queryPairs.stream().collect(Collectors.toMap(QueryPair::getKey, QueryPair::getValue))) .attribute("signal-flow-program", program)
@Test public void test_that_the_program_builder_builds_the_expected_program_no_location_key() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = new SignalFxScopeConfiguration(); scope.setScope("1.0.0"); scope.setScopeKey("version"); scope.setExtendedScopeParams(ImmutableMap.of( "env", "production", "_scope_key", "version")); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withQueryPair(new QueryPair("app", "cms")); builder.withQueryPair(new QueryPair("response_code", "400")); builder.withQueryPair(new QueryPair("uri", "/v2/auth/iam-principal")); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('app', 'cms') " + "and filter('response_code', '400') " + "and filter('uri', '/v2/auth/iam-principal') " + "and filter('version', '1.0.0') " + "and filter('env', 'production'))" + ".mean(by=['env', 'version']).publish()"; assertEquals(expected, builder.build()); }
@Test public void test_that_the_program_builder_builds_the_expected_program_with_no_query_pairs() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = new SignalFxScopeConfiguration(); scope.setScope("1.0.0"); scope.setScopeKey("version"); scope.setExtendedScopeParams(ImmutableMap.of( "env", "production", "_scope_key", "version")); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('version', '1.0.0') " + "and filter('env', 'production'))" + ".mean(by=['env', 'version']).publish()"; assertEquals(expected, builder.build()); }
@Override public String buildQuery(String metricsAccountName, CanaryConfig canaryConfig, CanaryMetricConfig canaryMetricConfig, CanaryScope canaryScope) { SignalFxScopeConfiguration scopeConfiguration = signalFxScopeConfigurationMap.get(metricsAccountName); SignalFxCanaryScope signalFxCanaryScope = (SignalFxCanaryScope) canaryScope; SignalFxCanaryMetricSetQueryConfig queryConfig = (SignalFxCanaryMetricSetQueryConfig) canaryMetricConfig.getQuery(); String aggregationMethod = Optional.ofNullable(queryConfig.getAggregationMethod()).orElse("mean"); List<QueryPair> queryPairs = Optional.ofNullable(queryConfig.getQueryPairs()).orElse(new LinkedList<>()); return SimpleSignalFlowProgramBuilder .create(queryConfig.getMetricName(), aggregationMethod, scopeConfiguration) .withQueryPairs(queryPairs) .withScope(signalFxCanaryScope) .build(); }
AccountCredentialsRepository accountCredentialsRepository) { SignalFxMetricsService.SignalFxMetricsServiceBuilder metricsServiceBuilder = SignalFxMetricsService.builder(); metricsServiceBuilder.accountName(name); .map(SignalFxManagedAccount::getName).collect(Collectors.toList()))); return metricsServiceBuilder.build();
String program = buildQuery(metricsAccountName, canaryConfig, canaryMetricConfig, canaryScope); .endTimeIso(Instant.ofEpochMilli(endEpochMilli).toString()) .stepMillis(stepMilli) .values(getTimeSeriesDataFromChannelMessages(signalFlowExecutionResult.getChannelMessages())) .tags(queryPairs.stream().collect(Collectors.toMap(QueryPair::getKey, QueryPair::getValue))) .attribute("signal-flow-program", program)
public static SimpleSignalFlowProgramBuilder create(String metricName, String aggregationMethod, SignalFxScopeConfiguration scopeConfiguration) { return new SimpleSignalFlowProgramBuilder(metricName, aggregationMethod, scopeConfiguration); }
public SimpleSignalFlowProgramBuilder withScope(SignalFxCanaryScope canaryScope) { scopeKeys.addAll(Optional.ofNullable(canaryScope.getExtendedScopeParams()).orElse(new HashMap<>()) .keySet().stream().filter(key -> !key.startsWith("_")).collect(Collectors.toList())); canaryScope.setScopeKey(Optional.ofNullable(canaryScope.getScopeKey()) .orElseGet(() -> Optional.ofNullable(scopeConfiguration.getDefaultScopeKey()) .orElseThrow(() -> new IllegalArgumentException("The SignalFx account must define a default scope key or " + "it must be supplied in the extendedScopeParams in the `_scope_key` key")))); Optional.ofNullable(Optional.ofNullable(canaryScope.getLocationKey()) .orElse(Optional.ofNullable(scopeConfiguration.getDefaultLocationKey()).orElse(null))) .ifPresent( locationKey -> { canaryScope.setLocationKey(locationKey); scopeKeys.add(locationKey); }); scopeKeys.add(canaryScope.getScopeKey()); filterSegments.add(buildFilterSegmentFromScope(canaryScope)); return this; }
@Test public void test_that_the_program_builder_builds_the_expected_program_with_extra_scope_qp_pairs() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = new SignalFxScopeConfiguration(); scope.setScope("1.0.0"); scope.setScopeKey("version"); scope.setExtendedScopeParams(ImmutableMap.of( "env", "production", "region", "us-west-2", "_scope_key", "version")); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withQueryPair(new QueryPair("app", "cms")); builder.withQueryPair(new QueryPair("response_code", "400")); builder.withQueryPair(new QueryPair("uri", "/v2/auth/iam-principal")); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('app', 'cms') " + "and filter('response_code', '400') " + "and filter('uri', '/v2/auth/iam-principal') " + "and filter('version', '1.0.0') " + "and filter('env', 'production') " + "and filter('region', 'us-west-2'))" + ".mean(by=['env', 'region', 'version']).publish()"; assertEquals(expected, builder.build()); }
@Test public void test_that_if_a_default_scope_key_was_defined_it_is_used_if_not_overwritten() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = SignalFxScopeConfiguration.builder() .defaultScopeKey("server_group") .build(); scope.setScope("my_microservice-control-v1"); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('server_group', 'my_microservice-control-v1'))" + ".mean(by=['server_group']).publish()"; assertEquals(expected, builder.build()); } }
@Test public void test_that_the_program_builder_builds_the_expected_program_1_qp() { String metricName = "request.count"; String aggregationMethod = "mean"; SignalFxCanaryScope scope = new SignalFxCanaryScope(); SignalFxScopeConfiguration scopeConfiguration = new SignalFxScopeConfiguration(); scope.setScope("1.0.0"); scope.setScopeKey("version"); scope.setExtendedScopeParams(ImmutableMap.of( "env", "production", "_scope_key", "version")); SimpleSignalFlowProgramBuilder builder = SimpleSignalFlowProgramBuilder .create(metricName, aggregationMethod, scopeConfiguration); builder.withQueryPair(new QueryPair("app", "cms")); builder.withScope(scope); String expected = "data('request.count', filter=" + "filter('app', 'cms') " + "and filter('version', '1.0.0') " + "and filter('env', 'production'))" + ".mean(by=['env', 'version']).publish()"; assertEquals(expected, builder.build()); }