├── .dockerignore ├── .gcloudignore ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml └── workflows │ ├── build.yml │ ├── pr.yml │ ├── release.yml │ └── release_info.sh ├── .gitignore ├── .idea ├── README.md ├── compiler.xml ├── copyright │ ├── ALS2.xml │ └── profiles_settings.xml ├── google-java-format.xml ├── gradle.xml └── vcs.xml ├── .mergify.yml ├── AUTHORS ├── Dockerfile ├── Dockerfile.compile ├── Dockerfile.slim ├── Dockerfile.ubuntu ├── LICENSE.txt ├── OSSMETADATA ├── OWNERS.md ├── README.md ├── build.gradle ├── docker-compose.yaml ├── docs ├── assets │ ├── canary-dimensional-metadata.png │ ├── canary-high-level-overview.png │ ├── canary-traffic-drill-down.png │ └── iqr-example.png ├── building-and-running-kayenta.md ├── canary-config.md ├── configuring-kayenta.md ├── faq.md ├── instrumenting-application-metrics-for-kayenta.md └── kayenta-standalone.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── halconfig ├── README.md └── kayenta.yml ├── json-formats.md ├── kayenta-atlas ├── kayenta-atlas.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── atlas │ │ │ ├── backends │ │ │ │ ├── AtlasStorageDatabase.java │ │ │ │ ├── AtlasStorageUpdater.java │ │ │ │ ├── AtlasStorageUpdaterService.java │ │ │ │ ├── BackendDatabase.java │ │ │ │ ├── BackendUpdater.java │ │ │ │ └── BackendUpdaterService.java │ │ │ ├── canary │ │ │ │ ├── AtlasCanaryScope.java │ │ │ │ └── AtlasCanaryScopeFactory.java │ │ │ ├── config │ │ │ │ ├── AtlasConfiguration.java │ │ │ │ ├── AtlasConfigurationProperties.java │ │ │ │ ├── AtlasManagedAccount.java │ │ │ │ └── AtlasSSEConverter.java │ │ │ ├── controllers │ │ │ │ └── AtlasFetchController.java │ │ │ ├── metrics │ │ │ │ └── AtlasMetricsService.java │ │ │ ├── model │ │ │ │ ├── AtlasResults.java │ │ │ │ ├── AtlasResultsHelper.java │ │ │ │ ├── AtlasStorage.java │ │ │ │ ├── Backend.java │ │ │ │ └── TimeseriesData.java │ │ │ ├── orca │ │ │ │ ├── AtlasFetchStage.java │ │ │ │ └── AtlasFetchTask.java │ │ │ ├── security │ │ │ │ ├── AtlasCredentials.java │ │ │ │ └── AtlasNamedAccountCredentials.java │ │ │ └── service │ │ │ │ ├── AtlasRemoteService.java │ │ │ │ ├── AtlasStorageRemoteService.java │ │ │ │ └── BackendsRemoteService.java │ │ │ └── canary │ │ │ └── providers │ │ │ └── metrics │ │ │ └── AtlasCanaryMetricSetQueryConfig.java │ └── resources │ │ ├── META-INF │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── controllers │ │ ├── empty.sse │ │ ├── sample-config.json │ │ ├── sample00.sse │ │ ├── sample01.sse │ │ ├── sample02.sse │ │ └── sample03.sse │ └── test │ ├── groovy │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── atlas │ │ ├── model │ │ └── AtlasResultsSpec.groovy │ │ └── orca │ │ └── AtlasFetchTaskSpec.groovy │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── atlas │ │ ├── BackendTest.java │ │ ├── BackendsTest.java │ │ ├── IntegrationTest.java │ │ └── config │ │ └── AtlasSSEConverterTest.java │ └── resources │ └── com │ └── netflix │ └── kayenta │ └── atlas │ ├── backends-location-test.json │ └── backends.json ├── kayenta-aws ├── kayenta-aws.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── aws │ │ ├── config │ │ ├── AwsConfiguration.java │ │ ├── AwsConfigurationProperties.java │ │ └── AwsManagedAccount.java │ │ └── security │ │ ├── AwsCredentials.java │ │ └── AwsNamedAccountCredentials.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-azure ├── kayenta-azure.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── azure │ │ ├── config │ │ ├── AzureConfiguration.java │ │ ├── AzureConfigurationProperties.java │ │ └── AzureManagedAccount.java │ │ └── security │ │ ├── AzureCredentials.java │ │ └── AzureNamedAccountCredentials.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-blobs ├── kayenta-blobs.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ └── blobs │ │ │ ├── config │ │ │ └── BlobsConfiguration.java │ │ │ └── storage │ │ │ ├── BlobsStorageService.java │ │ │ └── TestableBlobsStorageService.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── blobs │ └── storage │ └── TestableBlobsStorageServiceTest.java ├── kayenta-bom └── kayenta-bom.gradle ├── kayenta-core ├── kayenta-core.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ ├── canary │ │ ├── CanaryAdhocExecutionRequest.java │ │ ├── CanaryArchiveResultUpdateResponse.java │ │ ├── CanaryClassifierConfig.java │ │ ├── CanaryClassifierThresholdsConfig.java │ │ ├── CanaryConfig.java │ │ ├── CanaryConfigUpdateResponse.java │ │ ├── CanaryExecutionRequest.java │ │ ├── CanaryExecutionResponse.java │ │ ├── CanaryExecutionStatusResponse.java │ │ ├── CanaryJudge.java │ │ ├── CanaryJudgeConfig.java │ │ ├── CanaryMetricConfig.java │ │ ├── CanaryMetricSetQueryConfig.java │ │ ├── CanaryScope.java │ │ ├── CanaryScopeFactory.java │ │ ├── CanaryScopePair.java │ │ ├── ExecutionMapper.java │ │ ├── Metadata.java │ │ ├── orca │ │ │ ├── CanaryJudgeStage.java │ │ │ ├── CanaryJudgeTask.java │ │ │ ├── CanaryStageNames.java │ │ │ ├── CompareJudgeResultsStage.java │ │ │ ├── CompareJudgeResultsTask.java │ │ │ ├── SetupCanaryStage.java │ │ │ └── SetupCanaryTask.java │ │ ├── providers │ │ │ └── metrics │ │ │ │ └── QueryConfigUtils.java │ │ ├── results │ │ │ ├── CanaryAnalysisResult.java │ │ │ ├── CanaryJudgeGroupScore.java │ │ │ ├── CanaryJudgeMetricClassification.java │ │ │ ├── CanaryJudgeResult.java │ │ │ ├── CanaryJudgeScore.java │ │ │ ├── CanaryJudgeSummaryClassification.java │ │ │ └── CanaryResult.java │ │ └── util │ │ │ └── FetchControllerUtils.java │ │ ├── config │ │ ├── KayentaConfiguration.java │ │ └── KayentaSerializationConfigurationProperties.java │ │ ├── events │ │ ├── AbstractExecutionCompleteEventProcessor.java │ │ ├── CanaryExecutionCompletedEvent.java │ │ ├── CanaryExecutionCompletedProducer.java │ │ └── listeners │ │ │ └── ExecutionArchivalListener.java │ │ ├── index │ │ ├── CanaryConfigIndex.java │ │ ├── CanaryConfigIndexingAgent.java │ │ ├── config │ │ │ ├── CanaryConfigIndexAction.java │ │ │ ├── IndexConfiguration.java │ │ │ └── IndexConfigurationProperties.java │ │ └── readme.md │ │ ├── metrics │ │ ├── FatalQueryException.java │ │ ├── MapBackedMetricsServiceRepository.java │ │ ├── MetricSet.java │ │ ├── MetricSetMixerService.java │ │ ├── MetricSetPair.java │ │ ├── MetricsRetryConfigurationProperties.java │ │ ├── MetricsService.java │ │ ├── MetricsServiceRepository.java │ │ ├── RetryableQueryException.java │ │ ├── SynchronousQueryProcessor.java │ │ └── orca │ │ │ ├── MetricSetMixerServiceStage.java │ │ │ └── MetricSetMixerServiceTask.java │ │ ├── persistence │ │ └── config │ │ │ ├── JedisConfig.java │ │ │ └── RedisConnectionInfo.java │ │ ├── retrofit │ │ └── config │ │ │ ├── RemoteService.java │ │ │ ├── RetrofitClientConfiguration.java │ │ │ └── RetrofitClientFactory.java │ │ ├── security │ │ ├── AccountCredentials.java │ │ ├── AccountCredentialsRepository.java │ │ └── MapBackedAccountCredentialsRepository.java │ │ ├── service │ │ └── MetricSetPairListService.java │ │ ├── storage │ │ ├── MapBackedStorageServiceRepository.java │ │ ├── ObjectType.java │ │ ├── StandardObjectType.java │ │ ├── StorageService.java │ │ └── StorageServiceRepository.java │ │ └── util │ │ └── Retry.java │ └── test │ └── groovy │ └── com │ └── netflix │ └── kayenta │ ├── canary │ └── providers │ │ └── metrics │ │ ├── QueryConfigUtilsSpec.groovy │ │ ├── QueryConfigUtilsTest.java │ │ └── TestCanaryMetricSetQueryConfig.groovy │ ├── index │ ├── CanaryConfigIndexSpec.groovy │ ├── CanaryConfigIndexingAgentSpec.groovy │ └── TestNamedAccountCredentials.groovy │ ├── metrics │ ├── CanaryScopeSpec.groovy │ ├── MetricSetMixerServiceSpec.groovy │ ├── MetricSetSpec.groovy │ └── SynchronousQueryProcessorTest.java │ ├── security │ └── MapBackedAccountCredentialsRepositoryTest.java │ ├── storage │ └── MapBackedStorageServiceRepositoryTest.java │ └── util │ ├── KayentaSerializationConfigurationPropertiesTest.groovy │ └── RetrySpec.groovy ├── kayenta-datadog ├── kayenta-datadog.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── DatadogCanaryMetricSetQueryConfig.java │ │ │ ├── datadog │ │ │ ├── canary │ │ │ │ ├── DatadogCanaryScope.java │ │ │ │ └── DatadogCanaryScopeFactory.java │ │ │ ├── config │ │ │ │ ├── DatadogConfiguration.java │ │ │ │ ├── DatadogConfigurationProperties.java │ │ │ │ ├── DatadogConfigurationTestControllerDefaultProperties.java │ │ │ │ └── DatadogManagedAccount.java │ │ │ ├── controller │ │ │ │ └── DatadogFetchController.java │ │ │ ├── metrics │ │ │ │ └── DatadogMetricsService.java │ │ │ ├── orca │ │ │ │ ├── DatadogFetchStage.java │ │ │ │ └── DatadogFetchTask.java │ │ │ ├── security │ │ │ │ ├── DatadogCredentials.java │ │ │ │ └── DatadogNamedAccountCredentials.java │ │ │ └── service │ │ │ │ ├── DatadogRemoteService.java │ │ │ │ └── DatadogTimeSeries.java │ │ │ └── model │ │ │ ├── DatadogMetricDescriptor.java │ │ │ └── DatadogMetricDescriptorsResponse.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── groovy │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── datadog │ │ └── metrics │ │ └── DatadogMetricsServiceSpec.groovy │ └── java │ └── com │ └── netflix │ └── kayenta │ └── datadog │ ├── functional │ └── DatadogSecretsDoNotLeakWhenApiCalledFunctionalTest.java │ └── service │ └── DatadogTimeSeriesTest.java ├── kayenta-gcs ├── kayenta-gcs.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── gcs │ │ ├── config │ │ └── GcsConfiguration.java │ │ └── storage │ │ └── GcsStorageService.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-google ├── kayenta-google.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── google │ │ ├── config │ │ ├── GoogleConfiguration.java │ │ ├── GoogleConfigurationProperties.java │ │ └── GoogleManagedAccount.java │ │ └── security │ │ ├── GoogleClientFactory.java │ │ ├── GoogleJsonClientFactory.java │ │ └── GoogleNamedAccountCredentials.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-graphite ├── README.md ├── kayenta-graphite.gradle └── src │ ├── integration-test │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── config │ │ │ ├── GraphiteIntegrationTestConfig.java │ │ │ └── GraphiteMetricProvider.java │ │ │ └── graphite │ │ │ └── E2EIntegrationTest.java │ └── resources │ │ ├── config │ │ └── kayenta.yml │ │ └── integration-test-canary-config.json │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── GraphiteCanaryMetricSetQueryConfig.java │ │ │ └── graphite │ │ │ ├── canary │ │ │ ├── GraphiteCanaryScope.java │ │ │ └── GraphiteCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── GraphiteConfiguration.java │ │ │ ├── GraphiteConfigurationProperties.java │ │ │ ├── GraphiteConfigurationTestControllerDefaultProperties.java │ │ │ └── GraphiteManagedAccount.java │ │ │ ├── controller │ │ │ └── GraphiteFetchController.java │ │ │ ├── metrics │ │ │ └── GraphiteMetricsService.java │ │ │ ├── model │ │ │ ├── GraphiteMetricDescriptor.java │ │ │ ├── GraphiteMetricDescriptorsResponse.java │ │ │ └── GraphiteResults.java │ │ │ ├── orca │ │ │ ├── GraphiteFetchStage.java │ │ │ └── GraphiteFetchTask.java │ │ │ ├── security │ │ │ ├── GraphiteCredentials.java │ │ │ └── GraphiteNamedAccountCredentials.java │ │ │ └── service │ │ │ └── GraphiteRemoteService.java │ └── resources │ │ ├── META-INF │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── controllers │ │ └── sample-config.json │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── graphite │ └── IntegrationTest.java ├── kayenta-influxdb ├── docs │ └── metric-set-query-config.md ├── kayenta-influxdb.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── InfluxdbCanaryMetricSetQueryConfig.java │ │ │ └── influxdb │ │ │ ├── canary │ │ │ ├── InfluxDbCanaryScope.java │ │ │ └── InfluxDbCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── InfluxDbConfiguration.java │ │ │ ├── InfluxDbConfigurationProperties.java │ │ │ ├── InfluxDbConfigurationTestControllerDefaultProperties.java │ │ │ ├── InfluxDbManagedAccount.java │ │ │ └── InfluxDbResponseConverter.java │ │ │ ├── controller │ │ │ └── InfluxDbFetchController.java │ │ │ ├── metrics │ │ │ ├── InfluxDbMetricsService.java │ │ │ └── InfluxDbQueryBuilder.java │ │ │ ├── model │ │ │ └── InfluxDbResult.java │ │ │ ├── orca │ │ │ ├── InfluxDbFetchStage.java │ │ │ └── InfluxDbFetchTask.java │ │ │ ├── security │ │ │ ├── InfluxDbNamedAccountCredentials.java │ │ │ └── InfluxdbCredentials.java │ │ │ └── service │ │ │ └── InfluxDbRemoteService.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── influxdb │ ├── config │ └── InfluxDbResponseConverterTest.java │ └── service │ └── InfluxdbQueryBuilderTest.java ├── kayenta-integration-tests ├── kayenta-integration-tests.gradle └── src │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ ├── configuration │ │ ├── EmbeddedGraphiteBootstrapConfiguration.java │ │ ├── EmbeddedPrometheusBootstrapConfiguration.java │ │ └── MetricsReportingConfiguration.java │ │ ├── metrics │ │ ├── CanaryAnalysisCasesConfigurationProperties.java │ │ ├── MetricsGenerator.java │ │ ├── PercentilePrecisionMeterConfigurationFilter.java │ │ └── RandomProvider.java │ │ ├── steps │ │ └── StandaloneCanaryAnalysisSteps.java │ │ ├── tests │ │ ├── BaseIntegrationTest.java │ │ ├── ManagementTest.java │ │ ├── SwaggerTest.java │ │ └── standalone │ │ │ ├── GraphiteStandaloneCanaryAnalysisTest.java │ │ │ └── PrometheusStandaloneCanaryAnalysisTest.java │ │ └── utils │ │ ├── AwaitilityUtils.java │ │ ├── CanaryConfigReader.java │ │ └── EnvironmentUtils.java │ └── resources │ ├── META-INF │ └── spring.factories │ ├── application-base.yml │ ├── application-cases.yml │ ├── application-graphite.yml │ ├── application-prometheus.yml │ ├── canary-configs │ ├── graphite │ │ └── integration-test-cpu.json │ └── prometheus │ │ ├── integration-test-cpu.json │ │ └── muted-metric.json │ └── external │ ├── graphite │ └── storage-schemas.conf │ └── prometheus │ └── prometheus.yml ├── kayenta-integration ├── kayenta-integration.gradle └── src │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── spinnaker │ │ └── kayenta │ │ └── StandaloneContainerTest.java │ └── resources │ └── logback.xml ├── kayenta-judge ├── kayenta-judge.gradle └── src │ ├── main │ ├── resources │ │ └── META-INF │ │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── scala │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── judge │ │ ├── NetflixACAJudge.scala │ │ ├── RandomDummyJudge.scala │ │ ├── RemoteJudge.java │ │ ├── classifiers │ │ ├── metric │ │ │ ├── BaseMetricClassifier.scala │ │ │ ├── MannWhitneyClassifier.scala │ │ │ ├── MeanInequalityClassifier.scala │ │ │ └── RandomClassifier.scala │ │ └── score │ │ │ ├── BaseScoreClassifier.scala │ │ │ └── ThresholdScoreClassifier.scala │ │ ├── config │ │ ├── NetflixJudgeConfiguration.java │ │ ├── NetflixJudgeConfigurationProperties.java │ │ ├── RemoteJudgeConfiguration.java │ │ └── RemoteJudgeConfigurationProperties.java │ │ ├── detectors │ │ ├── BaseOutlierDetector.scala │ │ ├── IQRDetector.scala │ │ └── KSigmaDetector.scala │ │ ├── evaluation │ │ ├── BaseEvaluator.scala │ │ ├── BinaryClassificationEvaluator.scala │ │ └── Metrics.scala │ │ ├── model │ │ └── RemoteJudgeRequest.java │ │ ├── preprocessing │ │ ├── Transforms.scala │ │ └── Validators.scala │ │ ├── scorers │ │ ├── BaseScorer.scala │ │ ├── ScoringHelper.scala │ │ └── WeightedSumScorer.scala │ │ ├── service │ │ └── RemoteJudgeService.java │ │ ├── stats │ │ ├── DescriptiveStatistics.scala │ │ └── EffectSizes.scala │ │ └── utils │ │ ├── MapUtils.scala │ │ └── RandomUtils.scala │ └── test │ ├── resources │ └── test-config.json │ └── scala │ └── com │ └── netflix │ └── kayenta │ └── judge │ ├── ClassifierSuite.scala │ ├── DetectorSuite.scala │ ├── ScorerSuite.scala │ ├── StatisticSuite.scala │ ├── TestContextManagement.scala │ ├── TransformSuite.scala │ └── UtilsSuite.scala ├── kayenta-mannwhitney ├── kayenta-mannwhitney.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ └── mannwhitney │ │ │ └── BrentSolver.java │ └── scala │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── mannwhitney │ │ ├── MannWhitney.scala │ │ └── MannWhitneyException.scala │ └── test │ └── scala │ └── com │ └── netflix │ └── kayenta │ └── mannwhitney │ └── MannWhitneySuite.scala ├── kayenta-newrelic-insights ├── README.md ├── docs │ └── metric-set-query-config.md ├── kayenta-newrelic-insights.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── NewRelicCanaryMetricSetQueryConfig.java │ │ │ └── newrelic │ │ │ ├── canary │ │ │ ├── NewRelicCanaryScope.java │ │ │ └── NewRelicCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── NewRelicConfiguration.java │ │ │ ├── NewRelicConfigurationProperties.java │ │ │ ├── NewRelicConfigurationTestControllerDefaultProperties.java │ │ │ ├── NewRelicManagedAccount.java │ │ │ └── NewRelicScopeConfiguration.java │ │ │ ├── controller │ │ │ ├── NewRelicFetchController.java │ │ │ └── NewRelicFetchRequest.java │ │ │ ├── metrics │ │ │ ├── NewRelicMetricsService.java │ │ │ └── NewRelicQueryBuilderService.java │ │ │ ├── orca │ │ │ ├── NewRelicFetchStage.java │ │ │ └── NewRelicFetchTask.java │ │ │ ├── security │ │ │ ├── NewRelicCredentials.java │ │ │ └── NewRelicNamedAccountCredentials.java │ │ │ └── service │ │ │ ├── NewRelicRemoteService.java │ │ │ └── NewRelicTimeSeries.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── groovy │ └── com │ └── netflix │ └── kayenta │ └── newrelic │ └── metrics │ └── NewRelicQueryBuilderServiceSpec.groovy ├── kayenta-objectstore-configbin ├── kayenta-objectstore-configbin.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── configbin │ │ ├── config │ │ ├── ConfigBinConfiguration.java │ │ ├── ConfigBinConfigurationProperties.java │ │ ├── ConfigBinManagedAccount.java │ │ └── ConfigBinResponseConverter.java │ │ ├── security │ │ ├── ConfigBinAccountCredentials.java │ │ └── ConfigBinNamedAccountCredentials.java │ │ ├── service │ │ └── ConfigBinRemoteService.java │ │ └── storage │ │ └── ConfigBinStorageService.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-objectstore-memory ├── kayenta-objectstore-memory.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── memory │ │ ├── config │ │ ├── MemoryConfiguration.java │ │ ├── MemoryConfigurationProperties.java │ │ └── MemoryManagedAccount.java │ │ ├── security │ │ ├── MemoryAccountCredentials.java │ │ └── MemoryNamedAccountCredentials.java │ │ └── storage │ │ └── MemoryStorageService.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-orca ├── kayenta-orca.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ ├── config │ │ ├── OrcaCompositeHealthContributor.java │ │ └── OrcaConfiguration.java │ │ └── orca │ │ └── controllers │ │ ├── AdminController.java │ │ └── PipelineController.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-prometheus ├── kayenta-prometheus.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── PrometheusCanaryMetricSetQueryConfig.java │ │ │ └── prometheus │ │ │ ├── canary │ │ │ ├── PrometheusCanaryScope.java │ │ │ └── PrometheusCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── PrometheusConfiguration.java │ │ │ ├── PrometheusConfigurationProperties.java │ │ │ ├── PrometheusConfigurationTestControllerDefaultProperties.java │ │ │ ├── PrometheusManagedAccount.java │ │ │ └── PrometheusResponseConverter.java │ │ │ ├── controllers │ │ │ └── PrometheusFetchController.java │ │ │ ├── health │ │ │ ├── PrometheusHealthCache.java │ │ │ ├── PrometheusHealthIndicator.java │ │ │ └── PrometheusHealthJob.java │ │ │ ├── metrics │ │ │ ├── PrometheusMetricDescriptorsCache.java │ │ │ └── PrometheusMetricsService.java │ │ │ ├── model │ │ │ ├── PrometheusMetricDescriptor.java │ │ │ ├── PrometheusMetricDescriptorsResponse.java │ │ │ └── PrometheusResults.java │ │ │ ├── orca │ │ │ ├── PrometheusFetchStage.java │ │ │ └── PrometheusFetchTask.java │ │ │ └── service │ │ │ └── PrometheusRemoteService.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── groovy │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── prometheus │ │ └── metrics │ │ └── PrometheusMetricsServiceSpec.groovy │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── prometheus │ │ ├── config │ │ └── PrometheusHealthConfigurationTest.java │ │ ├── health │ │ ├── PrometheusHealthIndicatorTest.java │ │ └── PrometheusHealthJobTest.java │ │ ├── integration │ │ └── CanaryAnalysisPrometheusMetricsMixerServiceIntegrationTest.java │ │ ├── metrics │ │ └── PrometheusMetricDescriptorsCacheTest.java │ │ └── service │ │ └── PrometheusRemoteServiceTest.java │ └── resources │ ├── application-prometheusHealth.yml │ └── prometheus │ ├── rangeQueryEmpty.json │ ├── rangeQueryWithTags.json │ └── rangeQueryWithoutTags.json ├── kayenta-s3 ├── kayenta-s3.gradle └── src │ └── main │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── s3 │ │ ├── config │ │ └── S3Configuration.java │ │ └── storage │ │ └── S3StorageService.java │ └── resources │ └── META-INF │ └── spring │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports ├── kayenta-signalfx ├── README.md ├── docs │ └── metric-set-query-config.md ├── kayenta-signalfx.gradle └── src │ ├── integration-test │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── config │ │ │ └── SignalFxMockServiceReportingConfig.java │ │ │ └── signalfx │ │ │ ├── BaseSignalFxIntegrationTest.java │ │ │ ├── EndToEndCanaryIntegrationTests.java │ │ │ └── EndToEndStandaloneCanaryAnalysisIntegrationTests.java │ └── resources │ │ ├── config │ │ └── kayenta.yml │ │ └── integration-test-canary-config.json │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ ├── QueryPair.java │ │ │ │ └── SignalFxCanaryMetricSetQueryConfig.java │ │ │ └── signalfx │ │ │ ├── canary │ │ │ ├── SignalFxCanaryScope.java │ │ │ └── SignalFxCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── SignalFxConfiguration.java │ │ │ ├── SignalFxConfigurationProperties.java │ │ │ ├── SignalFxManagedAccount.java │ │ │ └── SignalFxScopeConfiguration.java │ │ │ ├── metrics │ │ │ ├── SignalFxMetricsService.java │ │ │ ├── SignalFxQueryBuilderService.java │ │ │ └── SimpleSignalFlowProgramBuilder.java │ │ │ ├── orca │ │ │ ├── SignalFxFetchStage.java │ │ │ └── SignalFxFetchTask.java │ │ │ ├── security │ │ │ ├── SignalFxCredentials.java │ │ │ └── SignalFxNamedAccountCredentials.java │ │ │ └── service │ │ │ ├── ErrorResponse.java │ │ │ ├── SignalFlowExecutionResult.java │ │ │ ├── SignalFxConverter.java │ │ │ ├── SignalFxRequestError.java │ │ │ └── SignalFxSignalFlowRemoteService.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── signalfx │ │ ├── config │ │ └── SignalFxConfigLoadTest.java │ │ ├── metrics │ │ ├── SignalFxQueryBuilderServiceTest.java │ │ └── SimpleSignalFlowProgramBuilderTest.java │ │ └── service │ │ └── SignalFxRemoteServiceTest.java │ └── resources │ └── signalfx-signalflow-response.text ├── kayenta-sql ├── kayenta-sql.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ └── sql │ │ │ ├── config │ │ │ ├── DataMigrationConfiguration.java │ │ │ ├── DataMigrationProperties.java │ │ │ └── SqlConfiguration.java │ │ │ ├── migration │ │ │ └── StorageDataMigrator.java │ │ │ └── storage │ │ │ ├── SqlStorageService.java │ │ │ ├── model │ │ │ ├── SqlBaseObject.java │ │ │ ├── SqlCanaryArchive.java │ │ │ ├── SqlCanaryConfig.java │ │ │ ├── SqlMetricSetPairs.java │ │ │ └── SqlMetricSets.java │ │ │ └── repo │ │ │ ├── SqlCanaryArchiveRepo.java │ │ │ ├── SqlCanaryConfigRepo.java │ │ │ ├── SqlMetricSetPairsRepo.java │ │ │ └── SqlMetricSetsRepo.java │ └── resources │ │ ├── META-INF │ │ └── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ └── db │ │ ├── changelog-master.yml │ │ └── changelog │ │ ├── 202303091551-create-canary-archive-table.yml │ │ ├── 202303091552-create-canary-config-table.yml │ │ ├── 202303091553-create-metric-sets-table.yml │ │ ├── 202303091554-create-metric-set-pairs-table.yml │ │ └── 202303091555-adjust-tables-for-postgres.yml │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── sql │ ├── migration │ └── StorageDataMigratorTest.java │ └── storage │ └── SqlStorageServiceTest.java ├── kayenta-stackdriver ├── kayenta-stackdriver.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── StackdriverCanaryMetricSetQueryConfig.java │ │ │ └── stackdriver │ │ │ ├── canary │ │ │ ├── StackdriverCanaryScope.java │ │ │ └── StackdriverCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── StackdriverConfiguration.java │ │ │ ├── StackdriverConfigurationProperties.java │ │ │ └── StackdriverConfigurationTestControllerDefaultProperties.java │ │ │ ├── controllers │ │ │ └── StackdriverFetchController.java │ │ │ ├── metrics │ │ │ └── StackdriverMetricsService.java │ │ │ └── orca │ │ │ ├── StackdriverFetchStage.java │ │ │ └── StackdriverFetchTask.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ ├── groovy │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── providers │ │ └── metrics │ │ └── StackdriverCanaryMetricSetQueryConfigSpec.groovy │ └── java │ └── com │ └── netflix │ └── kayenta │ └── stackdriver │ └── metrics │ └── StackdriverMetricsServiceTest.java ├── kayenta-standalone-canary-analysis ├── kayenta-standalone-canary-analysis.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ └── standalonecanaryanalysis │ │ │ ├── CanaryAnalysisConfig.java │ │ │ ├── config │ │ │ └── StandaloneCanaryAnalysisModuleConfiguration.java │ │ │ ├── controller │ │ │ └── StandaloneCanaryAnalysisController.java │ │ │ ├── domain │ │ │ ├── CanaryAnalysisAdhocExecutionRequest.java │ │ │ ├── CanaryAnalysisExecutionRequest.java │ │ │ ├── CanaryAnalysisExecutionRequestScope.java │ │ │ ├── CanaryAnalysisExecutionResponse.java │ │ │ ├── CanaryAnalysisExecutionResult.java │ │ │ ├── CanaryAnalysisExecutionStatusResponse.java │ │ │ ├── CanaryExecutionResult.java │ │ │ └── StageMetadata.java │ │ │ ├── event │ │ │ ├── StandaloneCanaryAnalysisExecutionCompletedEvent.java │ │ │ ├── StandaloneCanaryAnalysisExecutionCompletedProducer.java │ │ │ └── listener │ │ │ │ └── StandaloneCanaryAnalysisExecutionArchivalListener.java │ │ │ ├── orca │ │ │ ├── MonitorKayentaCanaryContext.java │ │ │ ├── RunCanaryContext.java │ │ │ ├── Stats.java │ │ │ ├── stage │ │ │ │ ├── GenerateCanaryAnalysisResultStage.java │ │ │ │ ├── RunCanaryStage.java │ │ │ │ └── SetupAndExecuteCanariesStage.java │ │ │ └── task │ │ │ │ ├── GenerateCanaryAnalysisResultTask.java │ │ │ │ ├── MonitorCanaryTask.java │ │ │ │ └── RunCanaryTask.java │ │ │ ├── service │ │ │ └── CanaryAnalysisService.java │ │ │ └── storage │ │ │ └── StandaloneCanaryAnalysisObjectType.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── standalonecanaryanalysis │ └── orca │ ├── stage │ └── SetupAndExecuteCanariesStageTest.java │ └── task │ └── GenerateCanaryAnalysisResultTaskTest.java ├── kayenta-wavefront ├── kayenta-wavefront.gradle └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── netflix │ │ │ └── kayenta │ │ │ ├── canary │ │ │ └── providers │ │ │ │ └── metrics │ │ │ │ └── WavefrontCanaryMetricSetQueryConfig.java │ │ │ └── wavefront │ │ │ ├── canary │ │ │ ├── WavefrontCanaryScope.java │ │ │ └── WavefrontCanaryScopeFactory.java │ │ │ ├── config │ │ │ ├── WavefrontConfiguration.java │ │ │ ├── WavefrontConfigurationProperties.java │ │ │ └── WavefrontManagedAccount.java │ │ │ ├── controller │ │ │ └── WavefrontFetchController.java │ │ │ ├── metrics │ │ │ └── WavefrontMetricsService.java │ │ │ ├── orca │ │ │ ├── WavefrontFetchStage.java │ │ │ └── WavefrontFetchTask.java │ │ │ ├── security │ │ │ ├── WavefrontCredentials.java │ │ │ └── WavefrontNamedAccountCredentials.java │ │ │ └── service │ │ │ ├── WavefrontRemoteService.java │ │ │ └── WavefrontTimeSeries.java │ └── resources │ │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── test │ └── java │ └── com │ └── netflix │ └── kayenta │ └── wavefront │ ├── canary │ └── WavefrontCanaryScopeFactoryTest.java │ ├── metrics │ └── WavefrontMetricsServiceTest.java │ └── service │ └── WavefrontTimeSeriesTest.java ├── kayenta-web ├── config │ ├── banner.txt │ └── kayenta.yml ├── etc │ ├── init │ │ └── kayenta.conf │ └── logrotate.d │ │ └── kayenta ├── kayenta-web.gradle ├── lib │ └── systemd │ │ └── system │ │ └── kayenta.service ├── pkg_scripts │ ├── postInstall.sh │ └── postUninstall.sh └── src │ ├── main │ └── java │ │ └── com │ │ └── netflix │ │ └── kayenta │ │ ├── Main.java │ │ ├── config │ │ ├── ApplicationConfiguration.java │ │ ├── WebConfiguration.java │ │ └── WebSecurityConfig.java │ │ ├── controllers │ │ ├── CanaryConfigController.java │ │ ├── CanaryController.java │ │ ├── CanaryJudgesController.java │ │ ├── CanaryResultArchiveController.java │ │ ├── ControllerExceptionHandler.java │ │ ├── CredentialsController.java │ │ ├── MetricSetListController.java │ │ ├── MetricSetPairListController.java │ │ ├── MetricsServiceDetail.java │ │ ├── MetricsServiceMetadataController.java │ │ └── MetricsServicesController.java │ │ └── filters │ │ └── KayentaCorsFilter.java │ └── test │ ├── java │ └── com │ │ └── netflix │ │ └── kayenta │ │ └── controllers │ │ ├── BaseControllerTest.java │ │ ├── CanaryConfigControllerTest.java │ │ └── CanaryControllerTest.java │ └── resources │ └── canary-configs │ └── duplicated-metric-name.json ├── lombok.config ├── scratch ├── atlas_canary_config.json ├── atlas_pipeline.json ├── newrelic_adhoc_canary.json ├── newrelic_canary_config.json ├── prometheus_canary_config.json ├── stackdriver_canary_config.json └── stackdriver_pipeline.json └── settings.gradle /.dockerignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | build/ 3 | docker-compose.yaml 4 | .git/ 5 | -------------------------------------------------------------------------------- /.gcloudignore: -------------------------------------------------------------------------------- 1 | # By default, everything inside .gitignore (as well as the .git directory and 2 | # the .gitignore file itself) is not uploaded to Google Cloud Build. But the 3 | # bintray publishing task requires the .git directory to uploaded. 4 | # 5 | # Adding this file overrides the default, so everything gets uploaded, but we 6 | # still want to exclude the large .gradle cache directory. 7 | .gradle 8 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | We prefer small, well tested pull requests. 2 | 3 | Please refer to [Contributing to Spinnaker](https://spinnaker.io/community/contributing/). 4 | 5 | When filling out a pull request, please consider the following: 6 | 7 | * Follow the commit message conventions [found here](https://spinnaker.io/community/contributing/submitting/). 8 | * Provide a descriptive summary for your changes. 9 | * If it fixes a bug or resolves a feature request, be sure to link to that issue. 10 | * Add inline code comments to changes that might not be obvious. 11 | * Squash your commits as you keep adding changes. 12 | * Add a comment to @spinnaker/reviewers for review if your issue has been outstanding for more than 3 days. 13 | 14 | Note that we are unlikely to accept pull requests that add features without prior discussion. The best way to propose a feature is to open an issue first and discuss your ideas there before implementing them. 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle/ 2 | build/ 3 | *.iml 4 | *.ipr 5 | *.iws 6 | out/ 7 | /.idea/ 8 | /.shelf/ 9 | .DS_Store 10 | .project 11 | .classpath 12 | .settings/ 13 | bin/ 14 | /dump.rdb 15 | /.vscode/ 16 | -------------------------------------------------------------------------------- /.idea/README.md: -------------------------------------------------------------------------------- 1 | # Spinnaker IntelliJ IDEA files 2 | 3 | IntelliJ IDEA will modify some of these files from their checked-in versions when the project is 4 | opened. To work around this, the Spinnaker Gradle plugin will mark these files in Git as "assume 5 | unchanged", telling Git to ignore any local changes. If you want to commit changes to these files, 6 | you will need to undo that. 7 | 8 | ```bash 9 | $ git update-index --no-assume-unchanged $FILENAME 10 | ``` 11 | -------------------------------------------------------------------------------- /.idea/copyright/ALS2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/google-java-format.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # Names should be added to this file with this pattern: 2 | # 3 | # For individuals: 4 | # Name 5 | # 6 | # For organizations: 7 | # Organization 8 | 9 | Netflix, Inc <*@netflix.com> 10 | Google, Inc <*@google.com> 11 | 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # Builder Image 3 | # 4 | FROM gradle:7.6.1-jdk17 AS builder 5 | 6 | # Prep build environment 7 | ENV GRADLE_USER_HOME=cache 8 | COPY . /tmp/workdir 9 | WORKDIR /tmp/workdir 10 | 11 | # Build kayenta 12 | # Doesn't run build because the integration tests try to spin up a Docker 13 | # container to talk to a Kayenta instance, which requires some Docker shenanigans. 14 | RUN gradle assemble 15 | 16 | # Unpack so release image can copy folder and be smaller 17 | RUN tar -xf /tmp/workdir/kayenta-web/build/distributions/kayenta.tar -C /opt 18 | 19 | # 20 | # Release Image 21 | # 22 | FROM alpine:3.20 23 | 24 | LABEL maintainer="delivery-engineering@netflix.com" 25 | 26 | RUN apk --no-cache add --update openjdk17-jre 27 | 28 | # Set where to look for config from 29 | ENV KAYENTA_OPTS=-Dspring.config.location=file:/opt/kayenta/config/kayenta.yml 30 | 31 | RUN mkdir -p /opt/spinnaker/plugins 32 | 33 | # Copy from builder image 34 | COPY --from=builder /opt/kayenta /opt/kayenta 35 | 36 | CMD ["/opt/kayenta/bin/kayenta"] 37 | -------------------------------------------------------------------------------- /Dockerfile.compile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 2 | RUN apk add --update \ 3 | openjdk17 \ 4 | && rm -rf /var/cache/apk 5 | LABEL maintainer="sig-platform@spinnaker.io" 6 | ENV GRADLE_USER_HOME /workspace/.gradle 7 | ENV GRADLE_OPTS -Xmx4g 8 | CMD ./gradlew --no-daemon kayenta-web:installDist -x test 9 | -------------------------------------------------------------------------------- /Dockerfile.slim: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 2 | LABEL maintainer="sig-platform@spinnaker.io" 3 | RUN apk --no-cache add --update bash curl openjdk17-jre 4 | RUN addgroup -S -g 10111 spinnaker 5 | RUN adduser -S -G spinnaker -u 10111 spinnaker 6 | COPY kayenta-web/build/install/kayenta /opt/kayenta 7 | RUN mkdir -p /opt/kayenta/plugins && chown -R spinnaker:nogroup /opt/kayenta/plugins 8 | USER spinnaker 9 | HEALTHCHECK CMD curl --fail http://localhost:8090/health 10 | CMD ["/opt/kayenta/bin/kayenta"] 11 | -------------------------------------------------------------------------------- /Dockerfile.ubuntu: -------------------------------------------------------------------------------- 1 | FROM ubuntu:jammy 2 | LABEL maintainer="sig-platform@spinnaker.io" 3 | RUN apt-get update && apt-get -y install curl openjdk-17-jre-headless wget 4 | RUN adduser --system --uid 10111 --group spinnaker 5 | COPY kayenta-web/build/install/kayenta /opt/kayenta 6 | RUN mkdir -p /opt/kayenta/plugins && chown -R spinnaker:nogroup /opt/kayenta/plugins 7 | USER spinnaker 8 | HEALTHCHECK CMD curl --fail http://localhost:8090/health 9 | CMD ["/opt/kayenta/bin/kayenta"] 10 | -------------------------------------------------------------------------------- /OSSMETADATA: -------------------------------------------------------------------------------- 1 | osslifecycle=active 2 | -------------------------------------------------------------------------------- /OWNERS.md: -------------------------------------------------------------------------------- 1 | csanden 2 | skandragon 3 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | redis: 4 | image: redis:latest 5 | ports: 6 | - 6379:6379 7 | kayenta: 8 | build: . 9 | ports: 10 | - 8090:8090 11 | environment: 12 | - services.redis.baseUrl=redis://redis:6379 13 | - redis.connection=redis://redis:6379 14 | volumes: 15 | - "~/.spinnaker/kayenta.yml:/opt/kayenta/config/kayenta.yml" 16 | depends_on: 17 | - redis 18 | -------------------------------------------------------------------------------- /docs/assets/canary-dimensional-metadata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinnaker/kayenta/a69573be9d8fededacf80817e4151a2c8df41276/docs/assets/canary-dimensional-metadata.png -------------------------------------------------------------------------------- /docs/assets/canary-high-level-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinnaker/kayenta/a69573be9d8fededacf80817e4151a2c8df41276/docs/assets/canary-high-level-overview.png -------------------------------------------------------------------------------- /docs/assets/canary-traffic-drill-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinnaker/kayenta/a69573be9d8fededacf80817e4151a2c8df41276/docs/assets/canary-traffic-drill-down.png -------------------------------------------------------------------------------- /docs/assets/iqr-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinnaker/kayenta/a69573be9d8fededacf80817e4151a2c8df41276/docs/assets/iqr-example.png -------------------------------------------------------------------------------- /docs/configuring-kayenta.md: -------------------------------------------------------------------------------- 1 | # Configuring Kayenta 2 | 3 | The best way to configure Kayenta if you are not using [Halyard](https://github.com/spinnaker/halyard) is to copy [kayenta.yml](../kayenta-web/config/kayenta.yml) and edit it. 4 | 5 | Please note that you need the following: 6 | 7 | ## At least one Configured Object Store 8 | 9 | Kayenta uses the object store to save its results, so this is essentially Kayenta's data store. 10 | 11 | ## At least one Configured Metrics Store 12 | 13 | Metric stores are the actual integration of a metric source (Prometheus, Stackdriver, Atlas, SignalFx, etc) into Kayenta. 14 | 15 | ## At least one Configured Configuration Store 16 | 17 | Configuration stores are where Kayenta will save the canary configuration it is instructed to save. The Object and Config store can be the same. 18 | 19 | ## Examples 20 | 21 | - See the reference [kayenta.yml](../kayenta-web/config/kayenta.yml) for the available config options. 22 | - See the [SignalFx Integration Test Config](../kayenta-signalfx/src/integration-test/resources/config/kayenta.yml) for a working example. 23 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | orcaVersion=8.64.0 2 | org.gradle.parallel=true 3 | spinnakerGradleVersion=8.32.1 4 | targetJava17=true 5 | org.gradle.jvmargs=-Xmx2g 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinnaker/kayenta/a69573be9d8fededacf80817e4151a2c8df41276/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /halconfig/README.md: -------------------------------------------------------------------------------- 1 | This directory contains skeleton Kayenta configs to which Halyard concatenates 2 | its generated deployment-specific config. 3 | 4 | These configs are **deprecated** and in general should not be further updated. 5 | To set a default config value, either set the value in 6 | `kayenta-web/config/kayenta.yml` or set a default in the code reading the 7 | config property. 8 | -------------------------------------------------------------------------------- /halconfig/kayenta.yml: -------------------------------------------------------------------------------- 1 | # halconfig 2 | -------------------------------------------------------------------------------- /kayenta-atlas/kayenta-atlas.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | api "com.squareup.retrofit:retrofit" 5 | api "com.squareup.retrofit:converter-jackson" 6 | api "org.apache.commons:commons-io:1.3.2" 7 | 8 | implementation "io.spinnaker.kork:kork-retrofit" 9 | } 10 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/config/AtlasConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | import lombok.Setter; 23 | 24 | public class AtlasConfigurationProperties { 25 | 26 | @Getter @Setter private int maxBackoffPeriodSeconds = 32; 27 | 28 | @Getter @Setter private int stageTimeoutMinutes = 3; 29 | 30 | @Getter private List accounts = new ArrayList<>(); 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/config/AtlasManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.config; 18 | 19 | import com.netflix.kayenta.security.AccountCredentials; 20 | import java.util.List; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.Data; 23 | 24 | @Data 25 | public class AtlasManagedAccount { 26 | 27 | @NotNull private String name; 28 | 29 | private List supportedTypes; 30 | 31 | @NotNull private String backendsJsonBaseUrl; 32 | 33 | private String fetchId; 34 | 35 | private List recommendedLocations; 36 | } 37 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/model/AtlasStorage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.atlas.model; 17 | 18 | import java.util.List; 19 | import java.util.Optional; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @EqualsAndHashCode 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | public class AtlasStorage { 29 | 30 | @NotNull @Getter private String global; 31 | 32 | @NotNull @Getter private String regional; 33 | 34 | @NotNull @Getter private List regions; 35 | 36 | public Optional getRegionalCnameForRegion(String region) { 37 | if (regions.contains(region)) { 38 | return Optional.of(regional.replace("$(region)", region)); 39 | } else { 40 | return Optional.empty(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/security/AtlasCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class AtlasCredentials { 28 | 29 | private static String applicationVersion = 30 | Optional.ofNullable(AtlasCredentials.class.getPackage().getImplementationVersion()) 31 | .orElse("Unknown"); 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/service/AtlasRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.service; 18 | 19 | import com.netflix.kayenta.atlas.model.AtlasResults; 20 | import java.util.List; 21 | import retrofit.http.GET; 22 | import retrofit.http.Query; 23 | 24 | public interface AtlasRemoteService { 25 | 26 | @GET("/api/v2/fetch") 27 | List fetch( 28 | @Query("q") String q, 29 | @Query("s") Long start, 30 | @Query("e") Long end, 31 | @Query("step") String step, 32 | @Query("id") String id, 33 | @Query("kayentaQueryUUID") String kayentaQueryUUID); 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/service/AtlasStorageRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.atlas.service; 17 | 18 | import com.netflix.kayenta.atlas.model.AtlasStorage; 19 | import java.util.Map; 20 | import retrofit.http.GET; 21 | 22 | public interface AtlasStorageRemoteService { 23 | 24 | @GET("/api/v1/atlas/storage.json") 25 | Map> fetch(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/atlas/service/BackendsRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.service; 18 | 19 | import com.netflix.kayenta.atlas.model.Backend; 20 | import java.util.List; 21 | import retrofit.http.GET; 22 | 23 | public interface BackendsRemoteService { 24 | 25 | @GET("/api/v1/atlas/backends.json") 26 | List fetch(); 27 | } 28 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/java/com/netflix/kayenta/canary/providers/metrics/AtlasCanaryMetricSetQueryConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.providers.metrics; 18 | 19 | import com.fasterxml.jackson.annotation.JsonTypeName; 20 | import com.netflix.kayenta.canary.CanaryMetricSetQueryConfig; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.*; 23 | 24 | @Builder 25 | @ToString 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | @JsonTypeName("atlas") 29 | public class AtlasCanaryMetricSetQueryConfig implements CanaryMetricSetQueryConfig { 30 | 31 | public static final String SERVICE_TYPE = "atlas"; 32 | 33 | @NotNull @Getter private String q; 34 | 35 | @Override 36 | public String getServiceType() { 37 | return SERVICE_TYPE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.atlas.config.AtlasConfiguration -------------------------------------------------------------------------------- /kayenta-atlas/src/main/resources/com/netflix/kayenta/controllers/empty.sse: -------------------------------------------------------------------------------- 1 | data: {"type":"close","message":"operation complete"} 2 | 3 | -------------------------------------------------------------------------------- /kayenta-atlas/src/main/resources/com/netflix/kayenta/controllers/sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "configVersion": 1.0, 3 | "description": "Example Automated Canary Analysis (ACA) Configuration", 4 | "metrics": [ 5 | { 6 | "service": "atlas", 7 | "name": "cpu", 8 | "query": { 9 | "type": "atlas", 10 | "q": "name,CpuRawUser,:eq,:sum" 11 | }, 12 | "extensions": { 13 | "canary": { } 14 | }, 15 | "groups": ["system"] 16 | }, 17 | { 18 | "service": "atlas", 19 | "name": "requests", 20 | "query": { 21 | "type": "atlas", 22 | "q": "name,apache.http.requests,:eq,(,requestCode,),:by,:sum" 23 | }, 24 | "extensions": { 25 | "canary": { } 26 | }, 27 | "groups": ["requests"] 28 | } 29 | ], 30 | "services": { 31 | "atlas": { 32 | "type": "atlas", 33 | "name": "atlas", 34 | "region": "us-east-1", 35 | "environment": "prod", 36 | "backend": { 37 | "deployment": "main", 38 | "dataset": "regional" 39 | } 40 | } 41 | }, 42 | "classifier": { 43 | "groupWeights": { 44 | "requests": 50.0, 45 | "system": 50.0 46 | }, 47 | "scoreThresholds": { 48 | "pass": 95.0, 49 | "marginal": 75.0 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /kayenta-atlas/src/test/resources/com/netflix/kayenta/atlas/backends-location-test.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "cname": "atlas-global.$(env).example.com", 4 | "target": "$(env).$(dataset)", 5 | "vip": "atlas_global-main:7001", 6 | "deployment": "main", 7 | "dataset": "global", 8 | "port": 7001, 9 | "environments": [ 10 | "test", 11 | "prod" 12 | ], 13 | "accounts": [ 14 | "12345", 15 | "23456" 16 | ], 17 | "regions": null, 18 | "step": "PT1M", 19 | "publishLatency": "PT5M", 20 | "retention": "P2W", 21 | "description": "Global endpoint that aggregates data from all supported regions." 22 | }, 23 | { 24 | "cname": "atlas-main.$(region).$(env).example.com", 25 | "target": "$(env).$(region)", 26 | "vip": "atlas_regional-$(deployment):7001", 27 | "deployment": "main", 28 | "dataset": "regional", 29 | "port": 7001, 30 | "environments": [ 31 | "test", 32 | "prod" 33 | ], 34 | "accounts": [ 35 | "34567", 36 | "45678" 37 | ], 38 | "regions": [ 39 | "us-west-1", 40 | "us-west-2", 41 | "us-east-1", 42 | "eu-west-1" 43 | ], 44 | "step": "PT1M", 45 | "publishLatency": "PT5M", 46 | "retention": "P2W", 47 | "description": "Main regional endpoint for the primary account with data for $(env).$(region)." 48 | } 49 | ] 50 | -------------------------------------------------------------------------------- /kayenta-aws/kayenta-aws.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | api "com.amazonaws:aws-java-sdk-s3" 5 | api "com.amazonaws:aws-java-sdk-sts" 6 | } 7 | -------------------------------------------------------------------------------- /kayenta-aws/src/main/java/com/netflix/kayenta/aws/config/AwsConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.aws.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class AwsConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-aws/src/main/java/com/netflix/kayenta/aws/security/AwsCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.aws.security; 18 | 19 | import java.util.Optional; 20 | import lombok.ToString; 21 | import lombok.extern.slf4j.Slf4j; 22 | 23 | @ToString 24 | @Slf4j 25 | public class AwsCredentials { 26 | 27 | private static String applicationVersion = 28 | Optional.ofNullable(AwsCredentials.class.getPackage().getImplementationVersion()) 29 | .orElse("Unknown"); 30 | } 31 | -------------------------------------------------------------------------------- /kayenta-aws/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.aws.config.AwsConfiguration -------------------------------------------------------------------------------- /kayenta-azure/kayenta-azure.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | api 'com.microsoft.azure:azure-storage:8.3.0' 5 | } 6 | -------------------------------------------------------------------------------- /kayenta-azure/src/main/java/com/netflix/kayenta/azure/config/AzureConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Microsoft Corporation. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.azure.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class AzureConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-azure/src/main/java/com/netflix/kayenta/azure/config/AzureManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Microsoft Corporation. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.azure.config; 18 | 19 | import com.netflix.kayenta.security.AccountCredentials; 20 | import java.util.List; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.Data; 23 | 24 | @Data 25 | public class AzureManagedAccount { 26 | 27 | @NotNull private String name; 28 | 29 | @NotNull private String storageAccountName; 30 | 31 | @NotNull private String accountAccessKey; 32 | 33 | @NotNull private String endpointSuffix; 34 | 35 | private String container; 36 | 37 | private String rootFolder; 38 | 39 | private List supportedTypes; 40 | } 41 | -------------------------------------------------------------------------------- /kayenta-azure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.azure.config.AzureConfiguration -------------------------------------------------------------------------------- /kayenta-blobs/kayenta-blobs.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | implementation project(":kayenta-azure") 4 | 5 | api 'com.microsoft.azure:azure-storage:8.3.0' 6 | testImplementation group: 'org.mockito', name: 'mockito-core', version: '1.9.10' 7 | } 8 | -------------------------------------------------------------------------------- /kayenta-blobs/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.blobs.config.BlobsConfiguration -------------------------------------------------------------------------------- /kayenta-bom/kayenta-bom.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: "java-platform" 18 | 19 | javaPlatform { 20 | allowDependencies() 21 | } 22 | 23 | dependencies { 24 | api(platform("io.spinnaker.orca:orca-bom:$orcaVersion")) 25 | 26 | constraints { 27 | rootProject 28 | .subprojects 29 | .findAll { it != project } 30 | .each { api(project(it.path)) } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-core/kayenta-core.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api "redis.clients:jedis" 3 | api "io.spinnaker.kork:kork-core" 4 | api "io.spinnaker.kork:kork-web" 5 | api "io.spinnaker.kork:kork-retrofit" 6 | api "com.netflix.spectator:spectator-api" 7 | 8 | api "io.spinnaker.orca:orca-core" 9 | api "io.spinnaker.orca:orca-retrofit" 10 | 11 | api "org.apache.commons:commons-text:1.11.0" 12 | api "org.springframework.boot:spring-boot-starter-actuator" 13 | api "org.springframework.boot:spring-boot-starter-json" 14 | api "net.logstash.logback:logstash-logback-encoder" 15 | 16 | api "javax.validation:validation-api" 17 | api "io.swagger.core.v3:swagger-annotations" 18 | 19 | testImplementation "io.spinnaker.kork:kork-jedis-test" 20 | } 21 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryAdhocExecutionRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary; 17 | 18 | import javax.validation.constraints.NotNull; 19 | import lombok.Data; 20 | 21 | @Data 22 | public class CanaryAdhocExecutionRequest { 23 | @NotNull protected CanaryConfig canaryConfig; 24 | 25 | @NotNull protected CanaryExecutionRequest executionRequest; 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryArchiveResultUpdateResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary; 18 | 19 | import javax.validation.constraints.NotNull; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | 23 | @Data 24 | @Builder 25 | public class CanaryArchiveResultUpdateResponse { 26 | 27 | @NotNull protected String pipelineId; 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryConfigUpdateResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary; 18 | 19 | import javax.validation.constraints.NotNull; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | 23 | @Data 24 | @Builder 25 | public class CanaryConfigUpdateResponse { 26 | 27 | @NotNull protected String canaryConfigId; 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryExecutionResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary; 17 | 18 | import javax.validation.constraints.NotNull; 19 | import lombok.AllArgsConstructor; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.NoArgsConstructor; 23 | 24 | @Data 25 | @Builder 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | public class CanaryExecutionResponse { 29 | 30 | @NotNull protected String canaryExecutionId; 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryJudge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary; 18 | 19 | import com.netflix.kayenta.canary.results.CanaryJudgeResult; 20 | import com.netflix.kayenta.metrics.MetricSetPair; 21 | import java.util.List; 22 | 23 | public abstract class CanaryJudge { 24 | public boolean isVisible() { 25 | return false; 26 | } 27 | 28 | public abstract String getName(); 29 | 30 | public abstract CanaryJudgeResult judge( 31 | CanaryConfig canaryConfig, 32 | CanaryClassifierThresholdsConfig orchestratorScoreThresholds, 33 | List metricSetPairList); 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryMetricConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import java.util.List; 21 | import java.util.Map; 22 | import javax.validation.constraints.NotNull; 23 | import lombok.*; 24 | 25 | @Builder(toBuilder = true) 26 | @ToString 27 | @NoArgsConstructor 28 | @AllArgsConstructor 29 | @JsonInclude(JsonInclude.Include.NON_NULL) 30 | public class CanaryMetricConfig { 31 | 32 | @NotNull @Getter private String name; 33 | 34 | @NotNull @Getter private CanaryMetricSetQueryConfig query; 35 | 36 | @NotNull @Singular @Getter private List groups; 37 | 38 | @NotNull @Singular @Getter private Map analysisConfigurations; 39 | 40 | @Getter private String scopeName; 41 | } 42 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryScopeFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary; 18 | 19 | public interface CanaryScopeFactory { 20 | 21 | boolean handles(String serviceType); 22 | 23 | CanaryScope buildCanaryScope(CanaryScope scope); 24 | } 25 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/CanaryScopePair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary; 17 | 18 | import javax.validation.constraints.NotNull; 19 | import lombok.AllArgsConstructor; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.NoArgsConstructor; 23 | 24 | @Data 25 | @Builder 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | public class CanaryScopePair { 29 | @NotNull CanaryScope controlScope; 30 | 31 | @NotNull CanaryScope experimentScope; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/Metadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary; 17 | 18 | import lombok.*; 19 | 20 | @Data 21 | @AllArgsConstructor 22 | @NoArgsConstructor 23 | public class Metadata { 24 | @Getter @NonNull protected String name; 25 | 26 | @Getter @NonNull protected String value; 27 | 28 | // 'hidden' is a UI-hint to show or not show this value by default in the UI, 29 | // likely in a generic way. 30 | @Getter protected Boolean hidden = false; 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/orca/CanaryStageNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary.orca; 17 | 18 | public class CanaryStageNames { 19 | public static final String REFID_SET_CONTEXT = "setupContext"; 20 | public static final String REFID_FETCH_CONTROL_PREFIX = "fetchControl"; 21 | public static final String REFID_FETCH_EXPERIMENT_PREFIX = "fetchExperiment"; 22 | public static final String REFID_MIX_METRICS = "mixMetrics"; 23 | public static final String REFID_JUDGE = "judge"; 24 | } 25 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryJudgeGroupScore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.results; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @JsonInclude(JsonInclude.Include.NON_NULL) 28 | public class CanaryJudgeGroupScore { 29 | @NotNull @Getter private String name; 30 | 31 | @NotNull @Getter private Double score; 32 | 33 | @NotNull @Getter private String classification; 34 | 35 | @Getter private String classificationReason; 36 | } 37 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryJudgeMetricClassification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.results; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @JsonInclude(JsonInclude.Include.NON_NULL) 28 | public class CanaryJudgeMetricClassification { 29 | 30 | @NotNull @Getter private String classification; 31 | 32 | @Getter private String classificationReason; 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryJudgeResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.results; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import java.util.List; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.*; 23 | 24 | @Builder 25 | @ToString 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | @JsonInclude(JsonInclude.Include.NON_NULL) 29 | public class CanaryJudgeResult { 30 | 31 | @NotNull @Getter private String judgeName; 32 | 33 | @NotNull @Getter private List results; 34 | 35 | @NotNull @Getter private List groupScores; 36 | 37 | @NotNull @Getter private CanaryJudgeScore score; 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryJudgeScore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.results; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @JsonInclude(JsonInclude.Include.NON_NULL) 28 | public class CanaryJudgeScore { 29 | 30 | @NotNull @Getter private double score; 31 | 32 | @NotNull @Getter private String classification; 33 | 34 | @NotNull @Getter private String classificationReason; 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryJudgeSummaryClassification.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.canary.results; 17 | 18 | import com.fasterxml.jackson.annotation.JsonInclude; 19 | import javax.validation.constraints.NotNull; 20 | import lombok.*; 21 | 22 | @Builder 23 | @ToString 24 | @NoArgsConstructor 25 | @AllArgsConstructor 26 | @JsonInclude(JsonInclude.Include.NON_NULL) 27 | public class CanaryJudgeSummaryClassification { 28 | 29 | @NotNull @Getter private String name; 30 | 31 | @Getter private int count; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/canary/results/CanaryResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.canary.results; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import java.time.Duration; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @JsonInclude(JsonInclude.Include.NON_NULL) 28 | public class CanaryResult { 29 | 30 | @Getter CanaryJudgeResult judgeResult; 31 | 32 | @Getter Duration canaryDuration; 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/config/KayentaSerializationConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.atlas.config; 18 | 19 | import lombok.Data; 20 | 21 | @Data 22 | public class KayentaSerializationConfigurationProperties { 23 | 24 | private boolean writeDatesAsTimestamps = false; 25 | 26 | private boolean writeDurationsAsTimestamps = false; 27 | } 28 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/index/config/CanaryConfigIndexAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.index.config; 18 | 19 | public enum CanaryConfigIndexAction { 20 | UPDATE, 21 | DELETE 22 | } 23 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/metrics/FatalQueryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.metrics; 17 | 18 | public class FatalQueryException extends RuntimeException { 19 | public FatalQueryException(String message) { 20 | super(message); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/metrics/MapBackedMetricsServiceRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.metrics; 18 | 19 | import java.util.Collections; 20 | import java.util.List; 21 | import java.util.Optional; 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | 24 | public class MapBackedMetricsServiceRepository implements MetricsServiceRepository { 25 | 26 | @Autowired(required = false) 27 | List metricsServices = Collections.emptyList(); 28 | 29 | @Override 30 | public Optional getOne(String accountName) { 31 | return metricsServices.stream().filter(m -> m.servicesAccount(accountName)).findFirst(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/metrics/MetricsServiceRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.metrics; 18 | 19 | import java.util.Optional; 20 | 21 | public interface MetricsServiceRepository { 22 | 23 | Optional getOne(String accountName); 24 | 25 | default MetricsService getRequiredOne(String accountName) { 26 | return getOne(accountName) 27 | .orElseThrow( 28 | () -> 29 | new IllegalArgumentException( 30 | "Unable to resolve metrics service " + accountName + ".")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/metrics/RetryableQueryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.metrics; 17 | 18 | public class RetryableQueryException extends RuntimeException { 19 | public RetryableQueryException(String message) { 20 | super(message); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/retrofit/config/RemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.retrofit.config; 18 | 19 | import javax.validation.constraints.NotNull; 20 | import lombok.Getter; 21 | import lombok.Setter; 22 | import lombok.ToString; 23 | 24 | @ToString 25 | public class RemoteService { 26 | 27 | @NotNull @Getter @Setter private String baseUrl; 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/storage/MapBackedStorageServiceRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.storage; 18 | 19 | import java.util.List; 20 | import java.util.Optional; 21 | 22 | public class MapBackedStorageServiceRepository implements StorageServiceRepository { 23 | 24 | private final List storageServices; 25 | 26 | public MapBackedStorageServiceRepository(List storageServices) { 27 | this.storageServices = storageServices; 28 | } 29 | 30 | @Override 31 | public Optional getOne(String accountName) { 32 | return storageServices.stream().filter(s -> s.servicesAccount(accountName)).findFirst(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/storage/StandardObjectType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Playtika 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.storage; 18 | 19 | import com.fasterxml.jackson.core.type.TypeReference; 20 | import lombok.Value; 21 | 22 | @Value 23 | public class StandardObjectType implements ObjectType { 24 | 25 | TypeReference typeReference; 26 | String group; 27 | String defaultFilename; 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-core/src/main/java/com/netflix/kayenta/storage/StorageServiceRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.storage; 18 | 19 | import java.util.Optional; 20 | 21 | public interface StorageServiceRepository { 22 | 23 | Optional getOne(String accountName); 24 | 25 | default StorageService getRequiredOne(String accountName) { 26 | return getOne(accountName) 27 | .orElseThrow( 28 | () -> 29 | new IllegalArgumentException( 30 | "Unable to resolve storage service " + accountName + ".")); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-core/src/test/groovy/com/netflix/kayenta/index/TestNamedAccountCredentials.groovy: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.index 18 | 19 | import com.netflix.kayenta.security.AccountCredentials 20 | 21 | class TestNamedAccountCredentials extends AccountCredentials { 22 | 23 | String getName() { 24 | return "some-account"; 25 | } 26 | 27 | String getType() { 28 | return "some-platform"; 29 | } 30 | 31 | @Override 32 | List getSupportedTypes() { 33 | [AccountCredentials.Type.CONFIGURATION_STORE] 34 | } 35 | 36 | @Override 37 | TestCredentials getCredentials() { 38 | new TestCredentials() 39 | } 40 | } 41 | 42 | class TestCredentials { 43 | } 44 | -------------------------------------------------------------------------------- /kayenta-datadog/kayenta-datadog.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | testImplementation "org.mock-server:mockserver-junit-jupiter:5.15.0" 5 | } 6 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/canary/DatadogCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import lombok.Data; 21 | import lombok.EqualsAndHashCode; 22 | import lombok.ToString; 23 | 24 | @Data 25 | @EqualsAndHashCode(callSuper = true) 26 | @ToString(callSuper = true) 27 | public class DatadogCanaryScope extends CanaryScope {} 28 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/canary/DatadogCanaryScopeFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import com.netflix.kayenta.canary.CanaryScopeFactory; 21 | import org.springframework.stereotype.Component; 22 | 23 | @Component 24 | public class DatadogCanaryScopeFactory implements CanaryScopeFactory { 25 | @Override 26 | public boolean handles(String serviceType) { 27 | return "datadog".equals(serviceType); 28 | } 29 | 30 | @Override 31 | public CanaryScope buildCanaryScope(CanaryScope scope) { 32 | return scope; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/config/DatadogConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.config; 18 | 19 | import java.time.Duration; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import lombok.Getter; 23 | import lombok.Setter; 24 | 25 | public class DatadogConfigurationProperties { 26 | 27 | // Datadog has an api limit of 100 metric retrievals per hour, default to 15 minutes here 28 | @Getter @Setter private long metadataCachingIntervalMS = Duration.ofMinutes(15).toMillis(); 29 | 30 | @Getter private List accounts = new ArrayList<>(); 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/config/DatadogConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | /** 23 | * This configuration class allows you to specify default values for the PrometheusFetchController. 24 | */ 25 | public class DatadogConfigurationTestControllerDefaultProperties { 26 | 27 | @Getter @Setter private String scope; 28 | 29 | @Getter @Setter private String start; 30 | 31 | @Getter @Setter private String end; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/config/DatadogManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.config; 18 | 19 | import com.netflix.kayenta.retrofit.config.RemoteService; 20 | import com.netflix.kayenta.security.AccountCredentials; 21 | import java.util.Collections; 22 | import java.util.List; 23 | import javax.validation.constraints.NotNull; 24 | import lombok.Data; 25 | 26 | @Data 27 | public class DatadogManagedAccount { 28 | @NotNull private String name; 29 | private String apiKey; 30 | private String applicationKey; 31 | 32 | @NotNull private RemoteService endpoint; 33 | 34 | private List supportedTypes = 35 | Collections.singletonList(AccountCredentials.Type.METRICS_STORE); 36 | } 37 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/datadog/security/DatadogCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.datadog.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class DatadogCredentials { 28 | private static String applicationVersion = 29 | Optional.ofNullable(DatadogCredentials.class.getPackage().getImplementationVersion()) 30 | .orElse("Unknown"); 31 | 32 | private String apiKey; 33 | private String applicationKey; 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/model/DatadogMetricDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.model; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | public class DatadogMetricDescriptor { 23 | 24 | private final String name; 25 | private final Map map; 26 | 27 | public DatadogMetricDescriptor(String name) { 28 | this.name = name; 29 | this.map = Collections.singletonMap("name", name); 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | // This is so we can efficiently serialize to json without having to construct the intermediate 37 | // map object on each query. 38 | public Map getMap() { 39 | return map; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/java/com/netflix/kayenta/model/DatadogMetricDescriptorsResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.model; 18 | 19 | import java.util.List; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.AllArgsConstructor; 22 | import lombok.Builder; 23 | import lombok.EqualsAndHashCode; 24 | import lombok.Getter; 25 | import lombok.NoArgsConstructor; 26 | import lombok.ToString; 27 | 28 | @Builder 29 | @ToString 30 | @EqualsAndHashCode 31 | @NoArgsConstructor 32 | @AllArgsConstructor 33 | public class DatadogMetricDescriptorsResponse { 34 | 35 | @NotNull @Getter private List metrics; 36 | } 37 | -------------------------------------------------------------------------------- /kayenta-datadog/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.datadog.config.DatadogConfiguration -------------------------------------------------------------------------------- /kayenta-gcs/kayenta-gcs.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | implementation project(":kayenta-google") 4 | 5 | api "io.spinnaker.kork:kork-exceptions" 6 | api "com.google.apis:google-api-services-storage" 7 | } 8 | -------------------------------------------------------------------------------- /kayenta-gcs/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.gcs.config.GcsConfiguration -------------------------------------------------------------------------------- /kayenta-google/kayenta-google.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | api "com.google.apis:google-api-services-monitoring" 5 | api "com.google.apis:google-api-services-storage" 6 | 7 | implementation "com.google.auth:google-auth-library-oauth2-http" 8 | implementation "com.google.http-client:google-http-client-jackson2" 9 | } 10 | -------------------------------------------------------------------------------- /kayenta-google/src/main/java/com/netflix/kayenta/google/config/GoogleConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.google.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class GoogleConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-google/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.google.config.GoogleConfiguration -------------------------------------------------------------------------------- /kayenta-graphite/src/integration-test/java/com/netflix/kayenta/config/GraphiteMetricProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.config; 18 | 19 | import java.time.Instant; 20 | import java.util.Random; 21 | 22 | class GraphiteMetricProvider { 23 | private int min; 24 | private int max; 25 | private String metricName; 26 | 27 | GraphiteMetricProvider(int min, int max, String metricName) { 28 | this.min = min; 29 | this.max = max; 30 | this.metricName = metricName; 31 | } 32 | 33 | String getRandomMetricWithinRange() { 34 | return String.format( 35 | "%s %d %d%n", 36 | metricName, new Random().nextInt((max - min) + 1) + min, Instant.now().getEpochSecond()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-graphite/src/integration-test/resources/integration-test-canary-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integration-test-canary-config", 3 | "description": "A simple config for integration testing the Graphite metric source Kayenta module.", 4 | "judge": { 5 | "judgeConfigurations": {}, 6 | "name": "NetflixACAJudge-v1.0" 7 | }, 8 | "metrics": [ 9 | { 10 | "name": "test", 11 | "query": { 12 | "metricName": "test.server.request.400.$scope", 13 | "type": "graphite" 14 | }, 15 | "analysisConfigurations": { 16 | "canary": { 17 | "direction": "increase" 18 | } 19 | }, 20 | "groups": [ 21 | "Integration Test Group" 22 | ], 23 | "scopeName": "default" 24 | } 25 | ], 26 | "classifier": { 27 | "groupWeights": { 28 | "Integration Test Group": 100 29 | }, 30 | "scoreThresholds": { 31 | "marginal": 50, 32 | "pass": 75 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/canary/GraphiteCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import lombok.Data; 21 | import lombok.EqualsAndHashCode; 22 | import lombok.ToString; 23 | 24 | @Data 25 | @EqualsAndHashCode(callSuper = true) 26 | @ToString(callSuper = true) 27 | public class GraphiteCanaryScope extends CanaryScope {} 28 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/canary/GraphiteCanaryScopeFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import com.netflix.kayenta.canary.CanaryScopeFactory; 21 | import org.springframework.stereotype.Component; 22 | 23 | @Component 24 | public class GraphiteCanaryScopeFactory implements CanaryScopeFactory { 25 | @Override 26 | public boolean handles(String serviceType) { 27 | return "graphite".equalsIgnoreCase(serviceType); 28 | } 29 | 30 | @Override 31 | public CanaryScope buildCanaryScope(CanaryScope scope) { 32 | return scope; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/config/GraphiteConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class GraphiteConfigurationProperties { 24 | @Getter private List accounts = new ArrayList<>(); 25 | } 26 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/config/GraphiteConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | public class GraphiteConfigurationTestControllerDefaultProperties { 23 | 24 | @Getter @Setter private String scope; 25 | 26 | @Getter @Setter private String start; 27 | 28 | @Getter @Setter private String end; 29 | } 30 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/config/GraphiteManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.config; 18 | 19 | import com.netflix.kayenta.retrofit.config.RemoteService; 20 | import com.netflix.kayenta.security.AccountCredentials; 21 | import java.util.List; 22 | import javax.validation.constraints.NotNull; 23 | import lombok.Data; 24 | 25 | @Data 26 | public class GraphiteManagedAccount { 27 | @NotNull private String name; 28 | 29 | @NotNull private RemoteService endpoint; 30 | 31 | private List supportedTypes; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/model/GraphiteMetricDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.model; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | public class GraphiteMetricDescriptor { 23 | 24 | private final String name; 25 | private final Map map; 26 | 27 | public GraphiteMetricDescriptor(String name) { 28 | this.name = name; 29 | this.map = Collections.singletonMap("name", name); 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public Map getMap() { 37 | return map; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/java/com/netflix/kayenta/graphite/security/GraphiteCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Snap Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.graphite.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class GraphiteCredentials { 28 | private static String applicationVersion = 29 | Optional.ofNullable(GraphiteCredentials.class.getPackage().getImplementationVersion()) 30 | .orElse("Unknown"); 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-graphite/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.graphite.config.GraphiteConfiguration -------------------------------------------------------------------------------- /kayenta-graphite/src/main/resources/com/netflix/kayenta/controllers/sample-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "configVersion": 1.0, 3 | "description": "Example Automated Canary Analysis (ACA) Configuration", 4 | "metrics": [ 5 | { 6 | "name": "CPU", 7 | "query": { 8 | "type": "graphite", 9 | "metricName": "system.cpu.user" 10 | }, 11 | "groups": [ 12 | "system" 13 | ], 14 | "analysisConfigurations": {}, 15 | "scopeName": "default" 16 | } 17 | ], 18 | "services": { 19 | "graphite": { 20 | "type": "graphite", 21 | "name": "graphite" 22 | } 23 | }, 24 | "classifier": { 25 | "groupWeights": { 26 | "requests": 50.0, 27 | "system": 50.0 28 | }, 29 | "scoreThresholds": { 30 | "pass": 95.0, 31 | "marginal": 75.0 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-influxdb/docs/metric-set-query-config.md: -------------------------------------------------------------------------------- 1 | ### InfluxdbCanaryMetricSetQueryConfig (CanaryMetricSetQueryConfig) 2 | Influxdb specific query configurations. 3 | 4 | #### Properties 5 | - `metricName` (string, optional): The measurement name where metrics are stored. This field is **required** UNLESS using `customInlineTemplate`. 6 | 7 | ``` 8 | "metricName": "cpu" 9 | ``` 10 | 11 | - `fields` (array[string], optional): The list of field names that need to be included in query. This field is **required** UNLESS using `customInlineTemplate`. See example below: 12 | 13 | ``` 14 | fields: [ 15 | "count" 16 | ] 17 | ``` 18 | 19 | - `customInlineTemplate` (string, optional): This allows you to write your own IQL statement. `${scope}` and `{timeFilter}` variables are **required** in the IQL statement. See example below: 20 | 21 | ``` 22 | customInlineTemplate: "SELECT sum(count) FROM cpu WHERE host = 'value1' AND ${scope} AND ${timeFilter} GROUP BY time(1m)" 23 | ``` 24 | 25 | - `type` (enum[string], required) 26 | - `influxdb` 27 | -------------------------------------------------------------------------------- /kayenta-influxdb/kayenta-influxdb.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | } 4 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/canary/InfluxDbCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import lombok.Data; 21 | import lombok.EqualsAndHashCode; 22 | import lombok.ToString; 23 | 24 | @Data 25 | @EqualsAndHashCode(callSuper = true) 26 | @ToString(callSuper = true) 27 | public class InfluxDbCanaryScope extends CanaryScope {} 28 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/canary/InfluxDbCanaryScopeFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import com.netflix.kayenta.canary.CanaryScopeFactory; 21 | import com.netflix.kayenta.canary.providers.metrics.InfluxdbCanaryMetricSetQueryConfig; 22 | import org.springframework.stereotype.Component; 23 | 24 | @Component 25 | public class InfluxDbCanaryScopeFactory implements CanaryScopeFactory { 26 | @Override 27 | public boolean handles(String serviceType) { 28 | return InfluxdbCanaryMetricSetQueryConfig.SERVICE_TYPE.equals(serviceType); 29 | } 30 | 31 | @Override 32 | public CanaryScope buildCanaryScope(CanaryScope scope) { 33 | return scope; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/config/InfluxDbConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class InfluxDbConfigurationProperties { 24 | @Getter private List accounts = new ArrayList<>(); 25 | } 26 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/config/InfluxDbConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | /** 23 | * This configuration class allows you to specify default values for the InfluxdbFetchController. 24 | */ 25 | public class InfluxDbConfigurationTestControllerDefaultProperties { 26 | 27 | @Getter @Setter private String scope; 28 | 29 | @Getter @Setter private String start; 30 | 31 | @Getter @Setter private String end; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/config/InfluxDbManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.config; 18 | 19 | import com.netflix.kayenta.retrofit.config.RemoteService; 20 | import com.netflix.kayenta.security.AccountCredentials; 21 | import java.util.List; 22 | import javax.validation.constraints.NotNull; 23 | import lombok.Data; 24 | 25 | @Data 26 | public class InfluxDbManagedAccount { 27 | @NotNull private String name; 28 | private String apiKey; 29 | private String applicationKey; 30 | 31 | @NotNull private RemoteService endpoint; 32 | 33 | private List supportedTypes; 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/security/InfluxdbCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | 23 | @Builder 24 | @Data 25 | public class InfluxdbCredentials { 26 | private static String applicationVersion = 27 | Optional.ofNullable(InfluxdbCredentials.class.getPackage().getImplementationVersion()) 28 | .orElse("Unknown"); 29 | 30 | private String dbName; 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/java/com/netflix/kayenta/influxdb/service/InfluxDbRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Joseph Motha 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.influxdb.service; 18 | 19 | import com.netflix.kayenta.influxdb.model.InfluxDbResult; 20 | import java.util.List; 21 | import retrofit.http.GET; 22 | import retrofit.http.Query; 23 | 24 | public interface InfluxDbRemoteService { 25 | 26 | // See 27 | // https://docs.influxdata.com/influxdb/v1.5/guides/querying_data/#querying-data-with-the-http-api 28 | @GET("/query") 29 | List query(@Query("db") String databaseName, @Query("q") String query); 30 | } 31 | -------------------------------------------------------------------------------- /kayenta-influxdb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.influxdb.config.InfluxDbConfiguration -------------------------------------------------------------------------------- /kayenta-integration-tests/kayenta-integration-tests.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | 3 | testImplementation project(":kayenta-web") 4 | testImplementation "io.rest-assured:rest-assured" 5 | testImplementation "org.awaitility:awaitility:4.0.3" 6 | testImplementation "io.micrometer:micrometer-registry-prometheus" 7 | testImplementation "io.micrometer:micrometer-registry-graphite" 8 | testImplementation "org.springframework.cloud:spring-cloud-starter-bootstrap" // needed for bootstrap phase when all embedded containers are setup 9 | testImplementation "com.playtika.testcontainers:embedded-redis:2.2.11" 10 | testImplementation "com.playtika.testcontainers:embedded-minio:2.2.11" 11 | testImplementation "org.testcontainers:testcontainers" 12 | } 13 | 14 | test.testLogging { 15 | showStandardStreams = true 16 | } 17 | 18 | gradle.taskGraph.whenReady { 19 | tasks.test.enabled = ( 20 | properties.getOrDefault('DISABLE_INTEGRATION_TESTS', 'false') != 'true' 21 | || System.getProperty('DISABLE_INTEGRATION_TESTS', 'false') != 'true' 22 | || System.getenv().getOrDefault('DISABLE_INTEGRATION_TESTS', 'false') != 'true' 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/java/com/netflix/kayenta/metrics/RandomProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Playtika 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.metrics; 17 | 18 | import java.util.Random; 19 | import lombok.RequiredArgsConstructor; 20 | 21 | @RequiredArgsConstructor 22 | public class RandomProvider { 23 | 24 | private final Random random = new Random(); 25 | 26 | public double getDouble(int lowerBound, int upperBound) { 27 | return getRandom(lowerBound, upperBound); 28 | } 29 | 30 | public long getLong(int lowerBound, int upperBound) { 31 | return getRandom(lowerBound, upperBound); 32 | } 33 | 34 | private int getRandom(int lowerBound, int upperBound) { 35 | if (lowerBound == upperBound) { 36 | return lowerBound; 37 | } 38 | return random.nextInt(upperBound - lowerBound) + lowerBound; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/java/com/netflix/kayenta/tests/SwaggerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Playtika 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.tests; 17 | 18 | import io.restassured.RestAssured; 19 | import org.junit.jupiter.api.Test; 20 | import org.springframework.http.HttpStatus; 21 | 22 | public class SwaggerTest extends BaseIntegrationTest { 23 | 24 | @Test 25 | public void swaggerUiIsPresent() { 26 | RestAssured.given() 27 | .port(serverPort) 28 | .get("/swagger-ui/index.html") 29 | .prettyPeek() 30 | .then() 31 | .assertThat() 32 | .statusCode(HttpStatus.OK.value()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/java/com/netflix/kayenta/utils/AwaitilityUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Playtika 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.utils; 17 | 18 | import static org.awaitility.Awaitility.await; 19 | 20 | import java.util.concurrent.TimeUnit; 21 | import org.awaitility.core.ThrowingRunnable; 22 | 23 | public class AwaitilityUtils { 24 | 25 | public static void awaitThirtySecondsUntil(ThrowingRunnable throwingRunnable) { 26 | await() 27 | .atMost(30, TimeUnit.SECONDS) 28 | .pollInterval(500, TimeUnit.MILLISECONDS) 29 | .untilAsserted(throwingRunnable); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/java/com/netflix/kayenta/utils/EnvironmentUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Playtika 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.utils; 17 | 18 | import java.util.Map; 19 | import org.springframework.core.env.ConfigurableEnvironment; 20 | import org.springframework.core.env.MapPropertySource; 21 | 22 | public class EnvironmentUtils { 23 | 24 | public static void registerPropertySource( 25 | String name, ConfigurableEnvironment environment, Map map) { 26 | MapPropertySource propertySource = new MapPropertySource(name, map); 27 | environment.getPropertySources().addFirst(propertySource); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 2 | com.netflix.kayenta.configuration.EmbeddedPrometheusBootstrapConfiguration,\ 3 | com.netflix.kayenta.configuration.EmbeddedGraphiteBootstrapConfiguration -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/application-graphite.yml: -------------------------------------------------------------------------------- 1 | kayenta: 2 | graphite: 3 | enabled: true 4 | accounts: 5 | - name: graphite-account 6 | endpoint: 7 | baseUrl: http://localhost:${embedded.graphite.httpPort} 8 | supportedTypes: 9 | - METRICS_STORE 10 | 11 | management: 12 | metrics: 13 | export: 14 | graphite: 15 | step: 1s 16 | port: ${embedded.graphite.picklePort} 17 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/application-prometheus.yml: -------------------------------------------------------------------------------- 1 | kayenta: 2 | prometheus: 3 | enabled: true 4 | health: 5 | enabled: true 6 | accounts: 7 | - name: prometheus-account 8 | endpoint: 9 | baseUrl: http://localhost:${embedded.prometheus.port} 10 | supportedTypes: 11 | - METRICS_STORE 12 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/canary-configs/graphite/integration-test-cpu.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integration-test-canary-config", 3 | "description": "A simple config for integration testing the Graphite metric source Kayenta module.", 4 | "judge": { 5 | "judgeConfigurations": {}, 6 | "name": "NetflixACAJudge-v1.0" 7 | }, 8 | "metrics": [ 9 | { 10 | "name": "test", 11 | "query": { 12 | "metricName": "integrationTestCpu.namespace.*.scope.$scope", 13 | "type": "graphite" 14 | }, 15 | "analysisConfigurations": { 16 | "canary": { 17 | "direction": "increase" 18 | } 19 | }, 20 | "groups": [ 21 | "Integration Test Group" 22 | ], 23 | "scopeName": "default" 24 | } 25 | ], 26 | "classifier": { 27 | "groupWeights": { 28 | "Integration Test Group": 100 29 | }, 30 | "scoreThresholds": { 31 | "marginal": 50, 32 | "pass": 75 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/canary-configs/prometheus/integration-test-cpu.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "integration-test-canary-config", 3 | "description": "A very simple config for integration testing", 4 | "judge": { 5 | "judgeConfigurations": {}, 6 | "name": "NetflixACAJudge-v1.0" 7 | }, 8 | "metrics": [ 9 | { 10 | "name": "CPU usage for service", 11 | "query": { 12 | "type": "prometheus", 13 | "metricName": "integration_test_cpu", 14 | "customFilterTemplate": "standard-template" 15 | }, 16 | "analysisConfigurations": { 17 | "canary": { 18 | "critical": true, 19 | "direction": "increase" 20 | } 21 | }, 22 | "groups": [ 23 | "pod-group" 24 | ], 25 | "scopeName": "default" 26 | } 27 | ], 28 | "templates": { 29 | "standard-template": "namespace='${namespace}', scope='${scope}'" 30 | }, 31 | "classifier": { 32 | "groupWeights": { 33 | "pod-group": 100 34 | }, 35 | "scoreThresholds": { 36 | "marginal": 50, 37 | "pass": 75 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/external/graphite/storage-schemas.conf: -------------------------------------------------------------------------------- 1 | # Schema definitions for Whisper files. Entries are scanned in order, 2 | # and first match wins. This file is scanned for changes every 60 seconds. 3 | # 4 | # Definition Syntax: 5 | # 6 | # [name] 7 | # pattern = regex 8 | # retentions = timePerPoint:timeToStore, timePerPoint:timeToStore, ... 9 | # 10 | # Remember: To support accurate aggregation from higher to lower resolution 11 | # archives, the precision of a longer retention archive must be 12 | # cleanly divisible by precision of next lower retention archive. 13 | # 14 | # Valid: 60s:7d,300s:30d (300/60 = 5) 15 | # Invalid: 180s:7d,300s:30d (300/180 = 3.333) 16 | # 17 | 18 | # Carbon's internal metrics. This entry should match what is specified in 19 | # CARBON_METRIC_PREFIX and CARBON_METRIC_INTERVAL settings 20 | [carbon] 21 | pattern = ^carbon\. 22 | retentions = 10m:6h,30m:90d 23 | 24 | [default] 25 | pattern = .* 26 | retentions = 1s:6h,1m:6d,1h:1800d 27 | -------------------------------------------------------------------------------- /kayenta-integration-tests/src/test/resources/external/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 1s 3 | 4 | scrape_configs: 5 | - job_name: kayenta-test-metrics 6 | metrics_path: /prometheus 7 | static_configs: 8 | - targets: ['host.testcontainers.internal:8081'] 9 | -------------------------------------------------------------------------------- /kayenta-integration/kayenta-integration.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | testImplementation "com.fasterxml.jackson.core:jackson-databind" 3 | testImplementation "org.assertj:assertj-core" 4 | testImplementation "org.junit.jupiter:junit-jupiter-api" 5 | testImplementation "org.slf4j:slf4j-api" 6 | testImplementation "org.testcontainers:testcontainers" 7 | testImplementation "org.testcontainers:junit-jupiter" 8 | testRuntimeOnly "ch.qos.logback:logback-classic" 9 | } 10 | 11 | test.configure { 12 | def fullDockerImageName = System.getenv('FULL_DOCKER_IMAGE_NAME') 13 | onlyIf("there is a docker image to test") { 14 | fullDockerImageName != null && fullDockerImageName.trim() != '' 15 | } 16 | } 17 | 18 | test { 19 | // So stdout and stderr from the just-built container are available in CI 20 | testLogging.showStandardStreams = true 21 | 22 | // Run the tests when the docker image changes 23 | inputs.property 'fullDockerImageName', System.getenv('FULL_DOCKER_IMAGE_NAME') 24 | } 25 | -------------------------------------------------------------------------------- /kayenta-judge/kayenta-judge.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'scala' 3 | 4 | dependencies { 5 | implementation project(':kayenta-core') 6 | implementation project(':kayenta-mannwhitney') 7 | 8 | api "org.apache.commons:commons-math3" 9 | 10 | // scala support 11 | api 'org.scala-lang:scala-library-all' 12 | api 'org.scala-lang:scala-reflect' 13 | api 'com.typesafe.scala-logging:scala-logging_2.12' 14 | testImplementation 'org.scalatest:scalatest_2.12' 15 | testRuntimeOnly 'org.scalatestplus:junit-5-9_2.12' 16 | } 17 | 18 | task scalaTest(dependsOn: ['testClasses'], type: JavaExec) { 19 | main = 'org.scalatest.tools.Runner' 20 | args = ['-R', 'build/classes/scala/test', '-o'] 21 | classpath = sourceSets.test.runtimeClasspath 22 | } 23 | 24 | test.dependsOn scalaTest // so that running "test" would run this first, then the JUnit tests 25 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.judge.config.NetflixJudgeConfiguration 2 | com.netflix.kayenta.judge.config.RemoteJudgeConfiguration -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/classifiers/score/BaseScoreClassifier.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.classifiers.score 18 | 19 | import com.netflix.kayenta.judge.scorers.ScoreResult 20 | 21 | sealed trait ScoreClassificationLabel 22 | case object Pass extends ScoreClassificationLabel 23 | case object Fail extends ScoreClassificationLabel 24 | case object Marginal extends ScoreClassificationLabel 25 | case object Nodata extends ScoreClassificationLabel 26 | case object Error extends ScoreClassificationLabel 27 | 28 | case class ScoreClassification(classification: ScoreClassificationLabel, reason: Option[String], score: Double) 29 | 30 | abstract class BaseScoreClassifier { 31 | def classify(scoreResults: ScoreResult): ScoreClassification 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/classifiers/score/ThresholdScoreClassifier.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.classifiers.score 18 | 19 | import com.netflix.kayenta.judge.scorers.ScoreResult 20 | 21 | 22 | class ThresholdScoreClassifier(passThreshold: Double, warningThreshold: Double) extends BaseScoreClassifier{ 23 | 24 | override def classify(scoreResults: ScoreResult): ScoreClassification = { 25 | val score = scoreResults.summaryScore 26 | if(score >= passThreshold){ 27 | ScoreClassification(Pass, scoreResults.reason, score) 28 | }else if(score >= warningThreshold){ 29 | ScoreClassification(Marginal, scoreResults.reason, score) 30 | }else{ 31 | ScoreClassification(Fail, scoreResults.reason, score) 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/config/NetflixJudgeConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.config; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | @Configuration 25 | @ComponentScan({"com.netflix.kayenta.judge"}) 26 | public class NetflixJudgeConfiguration { 27 | 28 | @Bean 29 | @ConfigurationProperties("kayenta.netflix.judge") 30 | NetflixJudgeConfigurationProperties netflixJudgeConfigurationProperties() { 31 | return new NetflixJudgeConfigurationProperties(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/config/NetflixJudgeConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.config; 18 | 19 | public class NetflixJudgeConfigurationProperties { 20 | 21 | private double tolerance = 0.25; 22 | private double confLevel = 0.98; 23 | 24 | public void setTolerance(double tolerance) { 25 | this.tolerance = tolerance; 26 | } 27 | 28 | public double getTolerance() { 29 | return tolerance; 30 | } 31 | 32 | public void setConfLevel(double confLevel) { 33 | this.confLevel = confLevel; 34 | } 35 | 36 | public double getConfLevel() { 37 | return confLevel; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/config/RemoteJudgeConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.config; 18 | 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 20 | import org.springframework.boot.context.properties.ConfigurationProperties; 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | @Configuration 25 | @ConditionalOnProperty("kayenta.remote-judge.enabled") 26 | public class RemoteJudgeConfiguration { 27 | 28 | @Bean 29 | @ConfigurationProperties("kayenta.remote-judge") 30 | RemoteJudgeConfigurationProperties remoteJudgeConfigurationProperties() { 31 | return new RemoteJudgeConfigurationProperties(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/config/RemoteJudgeConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.config; 18 | 19 | import com.netflix.kayenta.retrofit.config.RemoteService; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.Data; 22 | import org.springframework.validation.annotation.Validated; 23 | 24 | @Data 25 | @Validated 26 | public class RemoteJudgeConfigurationProperties { 27 | 28 | @NotNull private RemoteService endpoint; 29 | } 30 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/detectors/BaseOutlierDetector.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.detectors 18 | 19 | abstract class BaseOutlierDetector{ 20 | 21 | /** 22 | * Determine which data points are outliers 23 | * @param data array of samples 24 | * @return boolean array indicating which data points are anomalies 25 | */ 26 | def detect(data: Array[Double]): Array[Boolean] 27 | 28 | } -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/evaluation/BaseEvaluator.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.evaluation 18 | 19 | import com.netflix.kayenta.judge.Metric 20 | import com.netflix.kayenta.judge.classifiers.metric._ 21 | 22 | /** 23 | * Class that represents an instance of data and truth labels. 24 | * @param experiment experiment metric 25 | * @param control control metric 26 | * @param label ground truth label 27 | */ 28 | case class LabeledInstance(experiment: Metric, control: Metric, label: MetricClassificationLabel) 29 | 30 | /** 31 | * Abstract class for evaluators that compute metrics from predictions. 32 | */ 33 | abstract class BaseEvaluator{ 34 | def evaluate[T <: BaseMetricClassifier](classifier: T, dataset: List[LabeledInstance]): Map[String, Double] 35 | } -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/model/RemoteJudgeRequest.java: -------------------------------------------------------------------------------- 1 | package com.netflix.kayenta.judge.model; 2 | 3 | import com.netflix.kayenta.canary.CanaryClassifierThresholdsConfig; 4 | import com.netflix.kayenta.canary.CanaryConfig; 5 | import com.netflix.kayenta.metrics.MetricSetPair; 6 | import java.util.List; 7 | import javax.validation.constraints.NotNull; 8 | import lombok.Builder; 9 | import lombok.Getter; 10 | 11 | @Builder 12 | public class RemoteJudgeRequest { 13 | 14 | @NotNull @Getter private CanaryConfig canaryConfig; 15 | 16 | @NotNull @Getter private CanaryClassifierThresholdsConfig scoreThresholds; 17 | 18 | @NotNull @Getter private List metricSetPairList; 19 | } 20 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/scorers/BaseScorer.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.scorers 18 | 19 | import com.netflix.kayenta.canary.results.CanaryAnalysisResult 20 | 21 | case class ScoreResult(groupScores: Option[List[GroupScore]], summaryScore: Double, numMetrics: Double, reason: Option[String]) 22 | case class GroupScore(name: String, score: Double, noData: Boolean, labelCounts: Map[String, Int], numMetrics: Double) 23 | 24 | abstract class BaseScorer { 25 | def score(results: List[CanaryAnalysisResult]): ScoreResult 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/service/RemoteJudgeService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.judge.service; 18 | 19 | import com.netflix.kayenta.canary.results.CanaryJudgeResult; 20 | import com.netflix.kayenta.judge.model.RemoteJudgeRequest; 21 | import retrofit.http.Body; 22 | import retrofit.http.POST; 23 | 24 | public interface RemoteJudgeService { 25 | 26 | @POST("/judge") 27 | CanaryJudgeResult judge(@Body RemoteJudgeRequest body); 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-judge/src/main/scala/com/netflix/kayenta/judge/utils/RandomUtils.scala: -------------------------------------------------------------------------------- 1 | package com.netflix.kayenta.judge.utils 2 | 3 | import scala.util.Random 4 | 5 | object RandomUtils { 6 | 7 | private var random = new Random() 8 | 9 | /** 10 | * Initialize Random with the desired seed 11 | */ 12 | def init(seed: Int): Unit = { 13 | random = new Random(seed) 14 | } 15 | 16 | /** 17 | * Draw random samples from a normal (Gaussian) distribution. 18 | * @param mean Mean (“centre”) of the distribution. 19 | * @param stdev Standard deviation (spread or “width”) of the distribution. 20 | * @param numSamples Number of samples to draw 21 | */ 22 | def normal(mean: Double, stdev: Double, numSamples: Int): Array[Double] ={ 23 | List.fill(numSamples)(random.nextGaussian() * stdev + mean).toArray 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-judge/src/test/resources/test-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "configVersion": 1.0, 3 | "description": "Example Automated Canary Analysis (ACA) Configuration", 4 | "metrics": [ 5 | { 6 | "name": "cpu", 7 | "query": { 8 | "type": "atlas", 9 | "q": "name,CpuRawUser,:eq,:sum" 10 | }, 11 | "extensions": { 12 | "canary": { } 13 | }, 14 | "groups": ["system", "example"] 15 | }, 16 | { 17 | "name": "requests", 18 | "query": { 19 | "type": "atlas", 20 | "q": "name,apache.http.requests,:eq,:sum" 21 | }, 22 | "extensions": { 23 | "canary": { } 24 | }, 25 | "groups": ["requests", "example"] 26 | }, 27 | { 28 | "name": "foo", 29 | "query": { 30 | "type": "atlas", 31 | "q": "name,foo,:eq" 32 | }, 33 | "extensions": { 34 | "canary": { } 35 | }, 36 | "groups": ["bar"] 37 | } 38 | ], 39 | "classifier": { 40 | "groupWeights": { 41 | "requests": 50.0, 42 | "system": 50.0 43 | }, 44 | "scoreThresholds": { 45 | "pass": 95.0, 46 | "marginal": 75.0 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /kayenta-mannwhitney/kayenta-mannwhitney.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'scala' 3 | 4 | dependencies { 5 | api "org.apache.commons:commons-math3" 6 | 7 | api 'org.scala-lang:scala-library-all' 8 | api 'org.scala-lang:scala-reflect' 9 | api 'com.typesafe.scala-logging:scala-logging_2.12' 10 | 11 | testImplementation 'org.scalatest:scalatest_2.12' 12 | testRuntimeOnly 'org.scalatestplus:junit-5-9_2.12' 13 | } 14 | 15 | task scalaTest(dependsOn: ['testClasses'], type: JavaExec) { 16 | main = 'org.scalatest.tools.Runner' 17 | args = ['-R', 'build/classes/scala/test', '-o'] 18 | classpath = sourceSets.test.runtimeClasspath 19 | } 20 | 21 | test.dependsOn scalaTest // so that running "test" would run this first, then the JUnit tests 22 | -------------------------------------------------------------------------------- /kayenta-mannwhitney/src/main/scala/com/netflix/kayenta/mannwhitney/MannWhitneyException.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.mannwhitney 18 | 19 | class MannWhitneyException(message: String) extends RuntimeException; 20 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/README.md: -------------------------------------------------------------------------------- 1 | Newrelic Backend 2 | ==== 3 | 4 | Newrelic integration goes through the insights API by using a TIMESERIES-NRQL-query. The following lines explain, how to configure Kayenta accordingly. 5 | 6 | 1. In kayenta/kayenta-web/config/kayenta.yml enable the newrelic-block. Specificially, apiKey and applicationKey need to be set. 7 | 1. Create a canary-config either as part of an adhoc-canary or a separate one. See scratch/newrelic_canary_config.json for an example. All statements are basically NRQL parts. The select-statement is mandatory and is directly used as NRQL-SELECT. The q statement is optional and will be placed behind the "WHERE"-part of the query. 8 | 1. Prepare the executionRequest. An example can be seen here: scratch/newrelic_adhoc_canary.json. The important part is the "scope"-value. It will be concatenated to the "WHERE"-part of the NRQL query with extendedScopeParam _scope_key as key. This needs to differentiate between baseline and experiment scope. 9 | 10 | We recommend to manually set the step size to a value between 1 second and an upper value limit the maximum resolution because Insights-API has an upper limit for TIMESERIES queries. 11 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/docs/metric-set-query-config.md: -------------------------------------------------------------------------------- 1 | ### NewRelicCanaryMetricSetQueryConfig (CanaryMetricSetQueryConfig) 2 | New Relic Insights specific query configurations. 3 | #### Properties 4 | - `select` **SELECT count(\*) FROM Transaction** (string, optional) - NRQL query segment for WHERE clause. 5 | - `q` **httpStatusCode LIKE '5%'** (string, optional) - The full select query component of the NRQL statement. See the [NRQL Docs](https://docs.newrelic.com/docs/query-data/nrql-new-relic-query-language/getting-started/nrql-syntax-components-functions) 6 | - `customInlineTemplate` **SELECT count(\*) FROM Transaction TIMESERIES 60 seconds SINCE ${startEpochSeconds} UNTIL ${endEpochSeconds} WHERE httpStatusCode LIKE '5%' AND someKeyThatIsSetDuringDeployment LIKE '${someKeyThatWasProvidedInExtendedScopeParams}' AND autoScalingGroupName LIKE '${scope}' AND region LIKE '${location}'** (string, optional) - Custom inline template use this or `select` + `q`, this allows you to write your own NRQL, please note that your NRQL must use the TIMESERIES keyword. 7 | 8 | - `type` (enum[string], required) 9 | - `newrelic` 10 | 11 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/kayenta-newrelic-insights.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | } 4 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/canary/NewRelicCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Adobe 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.newrelic.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import javax.annotation.Nullable; 21 | import lombok.Data; 22 | import lombok.EqualsAndHashCode; 23 | import lombok.ToString; 24 | 25 | @Data 26 | @EqualsAndHashCode(callSuper = true) 27 | @ToString(callSuper = true) 28 | public class NewRelicCanaryScope extends CanaryScope { 29 | 30 | @Nullable private String scopeKey; 31 | @Nullable private String locationKey; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/config/NewRelicConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Adobe 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.newrelic.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class NewRelicConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/config/NewRelicConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Adobe 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.newrelic.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | /** 23 | * This configuration class allows you to specify default values for the NewRelic Fetch Controller. 24 | */ 25 | public class NewRelicConfigurationTestControllerDefaultProperties { 26 | 27 | @Getter @Setter private String scope; 28 | 29 | @Getter @Setter private String start; 30 | 31 | @Getter @Setter private String end; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/config/NewRelicScopeConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.netflix.kayenta.newrelic.config; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class NewRelicScopeConfiguration { 13 | 14 | private String defaultScopeKey; 15 | private String defaultLocationKey; 16 | } 17 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/security/NewRelicCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Adobe 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.newrelic.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class NewRelicCredentials { 28 | 29 | private static String applicationVersion = 30 | Optional.ofNullable(NewRelicCredentials.class.getPackage().getImplementationVersion()) 31 | .orElse("Unknown"); 32 | 33 | private String apiKey; 34 | private String applicationKey; 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/java/com/netflix/kayenta/newrelic/service/NewRelicRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Adobe 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.newrelic.service; 18 | 19 | import retrofit.http.GET; 20 | import retrofit.http.Header; 21 | import retrofit.http.Headers; 22 | import retrofit.http.Path; 23 | import retrofit.http.Query; 24 | 25 | public interface NewRelicRemoteService { 26 | 27 | @Headers("Accept: application/json") 28 | @GET("/v1/accounts/{application_key}/query") 29 | NewRelicTimeSeries getTimeSeries( 30 | @Header("X-Query-Key") String apiKey, 31 | @Path("application_key") String applicationKey, 32 | @Query("nrql") String query); 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-newrelic-insights/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.newrelic.config.NewRelicConfiguration -------------------------------------------------------------------------------- /kayenta-objectstore-configbin/kayenta-objectstore-configbin.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | } 4 | -------------------------------------------------------------------------------- /kayenta-objectstore-configbin/src/main/java/com/netflix/kayenta/configbin/config/ConfigBinConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.configbin.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class ConfigBinConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-objectstore-configbin/src/main/java/com/netflix/kayenta/configbin/config/ConfigBinManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.configbin.config; 18 | 19 | import com.netflix.kayenta.retrofit.config.RemoteService; 20 | import com.netflix.kayenta.security.AccountCredentials; 21 | import java.util.List; 22 | import javax.validation.constraints.NotNull; 23 | import lombok.Data; 24 | 25 | @Data 26 | public class ConfigBinManagedAccount { 27 | 28 | @NotNull private String name; 29 | 30 | @NotNull private RemoteService endpoint; 31 | 32 | @NotNull private String ownerApp; 33 | 34 | @NotNull private String configType; 35 | 36 | private List supportedTypes; 37 | } 38 | -------------------------------------------------------------------------------- /kayenta-objectstore-configbin/src/main/java/com/netflix/kayenta/configbin/security/ConfigBinAccountCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.configbin.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class ConfigBinAccountCredentials { 28 | // ConfigBin does not currently require authentication, so we do not need anything here. 29 | private static String applicationVersion = 30 | Optional.ofNullable(ConfigBinAccountCredentials.class.getPackage().getImplementationVersion()) 31 | .orElse("Unknown"); 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-objectstore-configbin/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.configbin.config.ConfigBinConfiguration -------------------------------------------------------------------------------- /kayenta-objectstore-memory/kayenta-objectstore-memory.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | } 4 | -------------------------------------------------------------------------------- /kayenta-objectstore-memory/src/main/java/com/netflix/kayenta/memory/config/MemoryConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.memory.config; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import lombok.Getter; 22 | 23 | public class MemoryConfigurationProperties { 24 | 25 | @Getter private List accounts = new ArrayList<>(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-objectstore-memory/src/main/java/com/netflix/kayenta/memory/config/MemoryManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.memory.config; 18 | 19 | import com.netflix.kayenta.security.AccountCredentials; 20 | import java.util.List; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.Data; 23 | 24 | @Data 25 | public class MemoryManagedAccount { 26 | 27 | @NotNull private String name; 28 | 29 | private List supportedTypes; 30 | } 31 | -------------------------------------------------------------------------------- /kayenta-objectstore-memory/src/main/java/com/netflix/kayenta/memory/security/MemoryAccountCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.memory.security; 18 | 19 | import java.util.Optional; 20 | import lombok.Builder; 21 | import lombok.Data; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | // TODO: Not sure what kind of credentials or configuration is really required here yet. 28 | public class MemoryAccountCredentials { 29 | 30 | private static String applicationVersion = 31 | Optional.ofNullable(MemoryAccountCredentials.class.getPackage().getImplementationVersion()) 32 | .orElse("Unknown"); 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-objectstore-memory/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.memory.config.MemoryConfiguration -------------------------------------------------------------------------------- /kayenta-orca/kayenta-orca.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | api "io.spinnaker.orca:keiko-spring" 3 | api "io.spinnaker.orca:orca-queue" 4 | api "io.spinnaker.orca:orca-queue-redis" 5 | api "io.spinnaker.orca:orca-redis" 6 | api "org.springframework.boot:spring-boot-starter-actuator" 7 | api "org.springframework.cloud:spring-cloud-commons" 8 | api "io.swagger.core.v3:swagger-annotations" 9 | 10 | // TODO(duftler): Move these to spinnaker-dependencies. 11 | testImplementation "io.spinnaker.orca:orca-test" 12 | 13 | testImplementation "com.natpryce:hamkrest" 14 | } 15 | -------------------------------------------------------------------------------- /kayenta-orca/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.config.OrcaConfiguration -------------------------------------------------------------------------------- /kayenta-prometheus/kayenta-prometheus.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | testImplementation "org.mock-server:mockserver-junit-jupiter:5.15.0" 5 | } 6 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/canary/PrometheusCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.canary; 18 | 19 | import com.netflix.kayenta.canary.CanaryScope; 20 | import lombok.Data; 21 | import lombok.EqualsAndHashCode; 22 | import lombok.ToString; 23 | 24 | @Data 25 | @EqualsAndHashCode(callSuper = true) 26 | @ToString(callSuper = true) 27 | public class PrometheusCanaryScope extends CanaryScope { 28 | 29 | private String project; 30 | 31 | /** @deprecated Use resourceType on PrometheusCanaryMetricSetQueryConfig instead. */ 32 | @Deprecated private String resourceType; 33 | } 34 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/config/PrometheusConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | /** 23 | * This configuration class allows you to specify default values for the PrometheusFetchController. 24 | */ 25 | public class PrometheusConfigurationTestControllerDefaultProperties { 26 | 27 | @Getter @Setter private String project; 28 | 29 | @Getter @Setter private String resourceType; 30 | 31 | @Getter @Setter private String location; 32 | 33 | @Getter @Setter private String scope; 34 | 35 | @Getter @Setter private String start; 36 | 37 | @Getter @Setter private String end; 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/health/PrometheusHealthCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Playtika. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.health; 18 | 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | public class PrometheusHealthCache { 23 | 24 | // this needs to be volatile since we need to guarantee that changes from async job are visible to 25 | // health indicator 26 | private volatile List healthStatuses = 27 | Collections.emptyList(); 28 | 29 | public void setHealthStatuses(List healthStatuses) { 30 | this.healthStatuses = healthStatuses; 31 | } 32 | 33 | public List getHealthStatuses() { 34 | return healthStatuses; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/model/PrometheusMetricDescriptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.model; 18 | 19 | import java.util.Collections; 20 | import java.util.Map; 21 | 22 | public class PrometheusMetricDescriptor { 23 | 24 | private final String name; 25 | private final Map map; 26 | 27 | public PrometheusMetricDescriptor(String name) { 28 | this.name = name; 29 | this.map = Collections.singletonMap("name", name); 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | // This is so we can efficiently serialize to json without having to construct the intermediate 37 | // map object on each query. 38 | public Map getMap() { 39 | return map; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/model/PrometheusMetricDescriptorsResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.model; 18 | 19 | import java.util.List; 20 | import javax.validation.constraints.NotNull; 21 | import lombok.AllArgsConstructor; 22 | import lombok.Builder; 23 | import lombok.EqualsAndHashCode; 24 | import lombok.Getter; 25 | import lombok.NoArgsConstructor; 26 | import lombok.ToString; 27 | 28 | @Builder 29 | @ToString 30 | @EqualsAndHashCode 31 | @NoArgsConstructor 32 | @AllArgsConstructor 33 | public class PrometheusMetricDescriptorsResponse { 34 | 35 | @NotNull @Getter private String status; 36 | 37 | @NotNull @Getter private List data; 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/java/com/netflix/kayenta/prometheus/model/PrometheusResults.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.prometheus.model; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.*; 23 | 24 | @Builder 25 | @ToString 26 | @EqualsAndHashCode 27 | @NoArgsConstructor 28 | @AllArgsConstructor 29 | public class PrometheusResults { 30 | 31 | @NotNull @Getter private String id; 32 | 33 | @NotNull @Getter private long startTimeMillis; 34 | 35 | @NotNull @Getter private long stepSecs; 36 | 37 | @NotNull @Getter private long endTimeMillis; 38 | 39 | @NotNull @Getter private Map tags; 40 | 41 | @NotNull @Getter private List values; 42 | } 43 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.prometheus.config.PrometheusConfiguration -------------------------------------------------------------------------------- /kayenta-prometheus/src/test/resources/application-prometheusHealth.yml: -------------------------------------------------------------------------------- 1 | kayenta: 2 | prometheus: 3 | enabled: true 4 | health: 5 | enabled: true 6 | accounts: 7 | - name: prometheus-account 8 | endpoint: 9 | baseUrl: http://localhost:${embedded.prometheus.port} 10 | supportedTypes: 11 | - METRICS_STORE 12 | -------------------------------------------------------------------------------- /kayenta-prometheus/src/test/resources/prometheus/rangeQueryEmpty.json: -------------------------------------------------------------------------------- 1 | {"status":"success","data":{"resultType":"matrix","result":[]}} 2 | -------------------------------------------------------------------------------- /kayenta-s3/kayenta-s3.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | implementation project(":kayenta-aws") 4 | 5 | api "com.amazonaws:aws-java-sdk-s3" 6 | api "org.apache.httpcomponents:httpclient" 7 | api "org.apache.httpcomponents:httpcore" 8 | } 9 | -------------------------------------------------------------------------------- /kayenta-s3/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.s3.config.S3Configuration -------------------------------------------------------------------------------- /kayenta-signalfx/docs/metric-set-query-config.md: -------------------------------------------------------------------------------- 1 | ### SignalFxCanaryMetricSetQueryConfig (CanaryMetricSetQueryConfig) 2 | SignalFx specific query configurations. 3 | See [The integration test canary-config json](../src/integration-test/resources/integration-test-canary-config.json) for a real example. 4 | #### Properties 5 | - `metricName` **requests.count** (string, required) - Metric name. 6 | - `queryPairs` (array[[QueryPair](#query-pairs)], optional) - List of query pairs. 7 | - `aggregationMethod` (enum[string], optional) - How to aggregate each time series of collected data to a single data point. Defaults to mean. 8 | - `bottom` 9 | - `count` 10 | - `max` 11 | - `mean` 12 | - `mean_plus_stddev` 13 | - `median` 14 | - `min` 15 | - `random` 16 | - `sample_stddev` 17 | - `sample_variance` 18 | - `size` 19 | - `stddev` 20 | - `sum` 21 | - `top` 22 | - `variance` 23 | - `type` (enum[string], required) 24 | - `signalfx` 25 | 26 | 27 | ### QueryPair (object) 28 | Can be dimensions, properties, or tags (for tags, use tag as key). 29 | #### Properties 30 | - `key` **uri** (string, required) - key 31 | - `value` **/v1/some-endpoint** - value 32 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/integration-test/resources/config/kayenta.yml: -------------------------------------------------------------------------------- 1 | redis: 2 | connection: redis://localhost:${redis.port} 3 | 4 | kayenta: 5 | 6 | signalfx: 7 | enabled: true 8 | accounts: 9 | - name: sfx-integration-test-account 10 | accessToken: ${kayenta.signalfx.apiKey} 11 | supportedTypes: 12 | - METRICS_STORE 13 | defaultScopeKey: canary-scope 14 | defaultLocationKey: location 15 | 16 | memory: 17 | enabled: true 18 | accounts: 19 | - name: in-memory-store 20 | supportedTypes: 21 | - OBJECT_STORE 22 | - CONFIGURATION_STORE 23 | 24 | configbin: 25 | enabled: false 26 | 27 | standaloneCanaryAnalysis.enabled: true 28 | 29 | keiko: 30 | queue: 31 | redis: 32 | queueName: kayenta.keiko.queue 33 | deadLetterQueueName: kayenta.keiko.queue.deadLetters 34 | 35 | spectator: 36 | applicationName: ${spring.application.name} 37 | webEndpoint: 38 | enabled: true 39 | 40 | spring: 41 | liquibase: 42 | change-log: classpath:db/changelog-master.yml 43 | autoconfigure: 44 | exclude: > 45 | org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, 46 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/canary/providers/metrics/QueryPair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.canary.providers.metrics; 19 | 20 | import lombok.AllArgsConstructor; 21 | import lombok.Data; 22 | import lombok.NoArgsConstructor; 23 | 24 | /** Can be used for Dimensions, Tags or Properties. For Tags, use 'tag' as the key. */ 25 | @Data 26 | @AllArgsConstructor 27 | @NoArgsConstructor 28 | public class QueryPair { 29 | 30 | private String key; 31 | private String value; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/canary/SignalFxCanaryScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.signalfx.canary; 19 | 20 | import com.netflix.kayenta.canary.CanaryScope; 21 | import lombok.Data; 22 | import lombok.EqualsAndHashCode; 23 | import lombok.ToString; 24 | 25 | @Data 26 | @EqualsAndHashCode(callSuper = true) 27 | @ToString(callSuper = true) 28 | public class SignalFxCanaryScope extends CanaryScope { 29 | 30 | private String scopeKey; 31 | private String locationKey; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/config/SignalFxConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.signalfx.config; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import lombok.Getter; 23 | 24 | public class SignalFxConfigurationProperties { 25 | 26 | @Getter private List accounts = new ArrayList<>(); 27 | } 28 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/config/SignalFxScopeConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.netflix.kayenta.signalfx.config; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @Builder 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class SignalFxScopeConfiguration { 13 | 14 | private String defaultScopeKey; 15 | private String defaultLocationKey; 16 | } 17 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/security/SignalFxCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.signalfx.security; 19 | 20 | import lombok.AllArgsConstructor; 21 | import lombok.Data; 22 | 23 | @Data 24 | @AllArgsConstructor 25 | public class SignalFxCredentials { 26 | 27 | private String accessToken; 28 | } 29 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/service/ErrorResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.signalfx.service; 19 | 20 | import java.util.Map; 21 | import lombok.Data; 22 | 23 | @Data 24 | public class ErrorResponse { 25 | 26 | private int code; 27 | private Map context; 28 | private String errorType; 29 | private String message; 30 | } 31 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/java/com/netflix/kayenta/signalfx/service/SignalFlowExecutionResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package com.netflix.kayenta.signalfx.service; 19 | 20 | import com.signalfx.signalflow.ChannelMessage; 21 | import java.util.List; 22 | import lombok.Builder; 23 | import lombok.Data; 24 | 25 | @Data 26 | @Builder 27 | public class SignalFlowExecutionResult { 28 | 29 | private List channelMessages; 30 | } 31 | -------------------------------------------------------------------------------- /kayenta-signalfx/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.signalfx.config.SignalFxConfiguration -------------------------------------------------------------------------------- /kayenta-sql/kayenta-sql.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | implementation "org.springframework.boot:spring-boot-starter-data-jpa" 4 | implementation "org.liquibase:liquibase-core" 5 | runtimeOnly "com.mysql:mysql-connector-j" 6 | runtimeOnly "org.postgresql:postgresql" 7 | } 8 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/config/DataMigrationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.config; 18 | 19 | import lombok.Data; 20 | import org.springframework.boot.context.properties.ConfigurationProperties; 21 | 22 | @Data 23 | @ConfigurationProperties("kayenta.data-migration") 24 | public class DataMigrationProperties { 25 | 26 | private boolean enabled; 27 | private String sourceAccountName; 28 | private String targetAccountName; 29 | private String sourceStorageServiceClassName; 30 | private String targetStorageServiceClassName; 31 | } 32 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/model/SqlBaseObject.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.model; 18 | 19 | import java.time.Instant; 20 | import javax.persistence.Id; 21 | import javax.persistence.MappedSuperclass; 22 | import lombok.Data; 23 | 24 | @Data 25 | @MappedSuperclass 26 | public class SqlBaseObject { 27 | 28 | @Id private String id; 29 | private String content; 30 | private Instant createdAt; 31 | private Instant updatedAt; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/model/SqlCanaryArchive.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.model; 18 | 19 | import javax.persistence.Entity; 20 | import javax.persistence.Table; 21 | 22 | @Entity 23 | @Table(name = "canary_archive") 24 | public class SqlCanaryArchive extends SqlBaseObject {} 25 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/model/SqlCanaryConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.model; 18 | 19 | import javax.persistence.Entity; 20 | import javax.persistence.Table; 21 | 22 | @Entity 23 | @Table(name = "canary_config") 24 | public class SqlCanaryConfig extends SqlBaseObject {} 25 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/model/SqlMetricSetPairs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.model; 18 | 19 | import javax.persistence.Entity; 20 | import javax.persistence.Table; 21 | 22 | @Entity 23 | @Table(name = "metric_set_pairs") 24 | public class SqlMetricSetPairs extends SqlBaseObject {} 25 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/model/SqlMetricSets.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.model; 18 | 19 | import javax.persistence.Entity; 20 | import javax.persistence.Table; 21 | 22 | @Entity 23 | @Table(name = "metric_sets") 24 | public class SqlMetricSets extends SqlBaseObject {} 25 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/repo/SqlCanaryArchiveRepo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.repo; 18 | 19 | import com.netflix.kayenta.sql.storage.model.SqlCanaryArchive; 20 | import org.springframework.data.repository.PagingAndSortingRepository; 21 | 22 | public interface SqlCanaryArchiveRepo 23 | extends PagingAndSortingRepository {} 24 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/repo/SqlCanaryConfigRepo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.repo; 18 | 19 | import com.netflix.kayenta.sql.storage.model.SqlCanaryConfig; 20 | import org.springframework.data.repository.PagingAndSortingRepository; 21 | 22 | public interface SqlCanaryConfigRepo extends PagingAndSortingRepository {} 23 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/repo/SqlMetricSetPairsRepo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.repo; 18 | 19 | import com.netflix.kayenta.sql.storage.model.SqlMetricSetPairs; 20 | import org.springframework.data.repository.PagingAndSortingRepository; 21 | 22 | public interface SqlMetricSetPairsRepo 23 | extends PagingAndSortingRepository {} 24 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/java/com/netflix/kayenta/sql/storage/repo/SqlMetricSetsRepo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 Armory, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.sql.storage.repo; 18 | 19 | import com.netflix.kayenta.sql.storage.model.SqlMetricSets; 20 | import org.springframework.data.repository.PagingAndSortingRepository; 21 | 22 | public interface SqlMetricSetsRepo extends PagingAndSortingRepository {} 23 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.sql.config.SqlConfiguration -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog-master.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - include: 3 | file: changelog/202303091551-create-canary-archive-table.yml 4 | relativeToChangelogFile: true 5 | - include: 6 | file: changelog/202303091552-create-canary-config-table.yml 7 | relativeToChangelogFile: true 8 | - include: 9 | file: changelog/202303091553-create-metric-sets-table.yml 10 | relativeToChangelogFile: true 11 | - include: 12 | file: changelog/202303091554-create-metric-set-pairs-table.yml 13 | relativeToChangelogFile: true 14 | - include: 15 | file: changelog/202303091555-adjust-tables-for-postgres.yml 16 | relativeToChangelogFile: true 17 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog/202303091551-create-canary-archive-table.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: create-canary-archive-table 4 | author: alexey.bedonik 5 | changes: 6 | - createTable: 7 | tableName: canary_archive 8 | columns: 9 | - column: 10 | name: id 11 | type: VARCHAR(255) 12 | constraints: 13 | primaryKey: true 14 | nullable: false 15 | - column: 16 | name: content 17 | type: JSON 18 | constraints: 19 | nullable: false 20 | - column: 21 | name: created_at 22 | type: datetime 23 | constraints: 24 | nullable: false 25 | - column: 26 | name: updated_at 27 | type: datetime 28 | constraints: 29 | nullable: false 30 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog/202303091552-create-canary-config-table.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: create-canary-config-table 4 | author: alexey.bedonik 5 | changes: 6 | - createTable: 7 | tableName: canary_config 8 | columns: 9 | - column: 10 | name: id 11 | type: VARCHAR(255) 12 | constraints: 13 | primaryKey: true 14 | nullable: false 15 | - column: 16 | name: content 17 | type: JSON 18 | constraints: 19 | nullable: false 20 | - column: 21 | name: created_at 22 | type: datetime 23 | constraints: 24 | nullable: false 25 | - column: 26 | name: updated_at 27 | type: datetime 28 | constraints: 29 | nullable: false 30 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog/202303091553-create-metric-sets-table.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: create-metric-sets-table 4 | author: alexey.bedonik 5 | changes: 6 | - createTable: 7 | tableName: metric_sets 8 | columns: 9 | - column: 10 | name: id 11 | type: VARCHAR(255) 12 | constraints: 13 | primaryKey: true 14 | nullable: false 15 | - column: 16 | name: content 17 | type: JSON 18 | constraints: 19 | nullable: false 20 | - column: 21 | name: created_at 22 | type: datetime 23 | constraints: 24 | nullable: false 25 | - column: 26 | name: updated_at 27 | type: datetime 28 | constraints: 29 | nullable: false 30 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog/202303091554-create-metric-set-pairs-table.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: create-metric-set-pairs-table 4 | author: alexey.bedonik 5 | changes: 6 | - createTable: 7 | tableName: metric_set_pairs 8 | columns: 9 | - column: 10 | name: id 11 | type: VARCHAR(255) 12 | constraints: 13 | primaryKey: true 14 | nullable: false 15 | - column: 16 | name: content 17 | type: JSON 18 | constraints: 19 | nullable: false 20 | - column: 21 | name: created_at 22 | type: datetime 23 | constraints: 24 | nullable: false 25 | - column: 26 | name: updated_at 27 | type: datetime 28 | constraints: 29 | nullable: false 30 | -------------------------------------------------------------------------------- /kayenta-sql/src/main/resources/db/changelog/202303091555-adjust-tables-for-postgres.yml: -------------------------------------------------------------------------------- 1 | databaseChangeLog: 2 | - changeSet: 3 | id: adjust-tables-for-postgres 4 | author: alexey.bedonik 5 | preConditions: 6 | - onFail: MARK_RAN 7 | - dbms: 8 | type: postgresql 9 | changes: 10 | - modifyDataType: 11 | tableName: canary_archive 12 | columnName: content 13 | newDataType: JSONB 14 | - modifyDataType: 15 | tableName: canary_config 16 | columnName: content 17 | newDataType: JSONB 18 | - modifyDataType: 19 | tableName: metric_sets 20 | columnName: content 21 | newDataType: JSONB 22 | - modifyDataType: 23 | tableName: metric_set_pairs 24 | columnName: content 25 | newDataType: JSONB 26 | -------------------------------------------------------------------------------- /kayenta-stackdriver/kayenta-stackdriver.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | implementation project(":kayenta-google") 4 | api "com.google.apis:google-api-services-monitoring" 5 | 6 | testImplementation 'org.mockito:mockito-inline' 7 | } 8 | -------------------------------------------------------------------------------- /kayenta-stackdriver/src/main/java/com/netflix/kayenta/stackdriver/config/StackdriverConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.stackdriver.config; 18 | 19 | import java.time.Duration; 20 | import lombok.Getter; 21 | import lombok.Setter; 22 | 23 | public class StackdriverConfigurationProperties { 24 | 25 | @Getter @Setter private long metadataCachingIntervalMS = Duration.ofSeconds(60).toMillis(); 26 | } 27 | -------------------------------------------------------------------------------- /kayenta-stackdriver/src/main/java/com/netflix/kayenta/stackdriver/config/StackdriverConfigurationTestControllerDefaultProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.stackdriver.config; 18 | 19 | import lombok.Getter; 20 | import lombok.Setter; 21 | 22 | /** 23 | * This configuration class allows you to specify default values for the StackdriverFetchController. 24 | */ 25 | public class StackdriverConfigurationTestControllerDefaultProperties { 26 | 27 | @Getter @Setter private String project; 28 | 29 | @Getter @Setter private String resourceType; 30 | 31 | @Getter @Setter private String location; 32 | 33 | @Getter @Setter private String scope; 34 | 35 | @Getter @Setter private String start; 36 | 37 | @Getter @Setter private String end; 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-stackdriver/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.stackdriver.config.StackdriverConfiguration -------------------------------------------------------------------------------- /kayenta-standalone-canary-analysis/kayenta-standalone-canary-analysis.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | 4 | } 5 | 6 | test { 7 | testLogging { 8 | events "passed", "skipped", "failed" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /kayenta-standalone-canary-analysis/src/main/java/com/netflix/kayenta/standalonecanaryanalysis/config/StandaloneCanaryAnalysisModuleConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.standalonecanaryanalysis.config; 18 | 19 | import lombok.extern.slf4j.Slf4j; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 21 | import org.springframework.context.annotation.ComponentScan; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | @Configuration 25 | @ConditionalOnProperty("kayenta.standalone-canary-analysis.enabled") 26 | @ComponentScan({"com.netflix.kayenta.standalonecanaryanalysis"}) 27 | @Slf4j 28 | public class StandaloneCanaryAnalysisModuleConfiguration {} 29 | -------------------------------------------------------------------------------- /kayenta-standalone-canary-analysis/src/main/java/com/netflix/kayenta/standalonecanaryanalysis/domain/CanaryAnalysisExecutionResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.standalonecanaryanalysis.domain; 18 | 19 | import io.swagger.v3.oas.annotations.media.Schema; 20 | import lombok.*; 21 | 22 | @Data 23 | @Builder 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | @Schema(description = "Wrapper object around the canary analysis execution id.") 27 | public class CanaryAnalysisExecutionResponse { 28 | 29 | @NonNull 30 | @Schema(description = "The id of the execution", example = "01CYZCD53RBX2KR2Q9GY0218TV") 31 | protected String canaryAnalysisExecutionId; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-standalone-canary-analysis/src/main/java/com/netflix/kayenta/standalonecanaryanalysis/orca/Stats.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nike, inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.standalonecanaryanalysis.orca; 18 | 19 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 20 | import lombok.AllArgsConstructor; 21 | import lombok.Builder; 22 | import lombok.Data; 23 | import lombok.NoArgsConstructor; 24 | import lombok.ToString; 25 | 26 | /** Internal model used in the canary analysis pipeline execution stages */ 27 | @Data 28 | @Builder 29 | @ToString 30 | @AllArgsConstructor 31 | @NoArgsConstructor 32 | @JsonIgnoreProperties(ignoreUnknown = true) 33 | public class Stats { 34 | Integer count; 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-standalone-canary-analysis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.standalonecanaryanalysis.config.StandaloneCanaryAnalysisModuleConfiguration -------------------------------------------------------------------------------- /kayenta-wavefront/kayenta-wavefront.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(":kayenta-core") 3 | } 4 | -------------------------------------------------------------------------------- /kayenta-wavefront/src/main/java/com/netflix/kayenta/wavefront/config/WavefrontConfigurationProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Intuit, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.wavefront.config; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import lombok.Getter; 21 | 22 | public class WavefrontConfigurationProperties { 23 | @Getter private List accounts = new ArrayList<>(); 24 | } 25 | -------------------------------------------------------------------------------- /kayenta-wavefront/src/main/java/com/netflix/kayenta/wavefront/config/WavefrontManagedAccount.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Intuit, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.wavefront.config; 17 | 18 | import com.netflix.kayenta.retrofit.config.RemoteService; 19 | import com.netflix.kayenta.security.AccountCredentials; 20 | import java.util.List; 21 | import javax.validation.constraints.NotNull; 22 | import lombok.Data; 23 | 24 | @Data 25 | public class WavefrontManagedAccount { 26 | @NotNull private String name; 27 | private String apiToken; 28 | 29 | @NotNull private RemoteService endpoint; 30 | 31 | private List supportedTypes; 32 | } 33 | -------------------------------------------------------------------------------- /kayenta-wavefront/src/main/java/com/netflix/kayenta/wavefront/security/WavefrontCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Intuit, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.wavefront.security; 17 | 18 | import java.util.Optional; 19 | import lombok.Builder; 20 | import lombok.Data; 21 | import lombok.NonNull; 22 | import lombok.extern.slf4j.Slf4j; 23 | 24 | @Builder 25 | @Data 26 | @Slf4j 27 | public class WavefrontCredentials { 28 | 29 | private static String applicationVersion = 30 | Optional.ofNullable(WavefrontCredentials.class.getPackage().getImplementationVersion()) 31 | .orElse("Unknown"); 32 | 33 | @NonNull private String apiToken; 34 | 35 | public String getApiToken() { 36 | return "Bearer " + apiToken; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-wavefront/src/main/java/com/netflix/kayenta/wavefront/service/WavefrontRemoteService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Intuit, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.netflix.kayenta.wavefront.service; 17 | 18 | import retrofit.http.GET; 19 | import retrofit.http.Header; 20 | import retrofit.http.Query; 21 | 22 | public interface WavefrontRemoteService { 23 | @GET("/api/v2/chart/api") 24 | WavefrontTimeSeries fetch( 25 | @Header("Authorization") String authorization, 26 | @Query("n") String name, 27 | @Query("q") String query, 28 | @Query("s") Long startTime, 29 | @Query("e") Long endTime, 30 | @Query("g") String granularity, 31 | @Query("summarization") String summarization, 32 | @Query("listMode") boolean listMode, 33 | @Query("strict") boolean strict, 34 | @Query("sorted") boolean sorted); 35 | } 36 | -------------------------------------------------------------------------------- /kayenta-wavefront/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | com.netflix.kayenta.wavefront.config.WavefrontConfiguration -------------------------------------------------------------------------------- /kayenta-web/config/banner.txt: -------------------------------------------------------------------------------- 1 | __ __ ______ __ __ ______ __ __ ______ ______ 2 | /\ \/ / /\ __ \ /\ \_\ \ /\ ___\ /\ "-.\ \ /\__ _\ /\ __ \ 3 | \ \ _"-. \ \ __ \ \ \____ \ \ \ __\ \ \ \-. \ \/_/\ \/ \ \ __ \ 4 | \ \_\ \_\ \ \_\ \_\ \/\_____\ \ \_____\ \ \_\\"\_\ \ \_\ \ \_\ \_\ 5 | \/_/\/_/ \/_/\/_/ \/_____/ \/_____/ \/_/ \/_/ \/_/ \/_/\/_/ 6 | -------------------------------------------------------------------------------- /kayenta-web/etc/init/kayenta.conf: -------------------------------------------------------------------------------- 1 | description "kayenta" 2 | 3 | start on filesystem or runlevel [2345] 4 | 5 | setuid spinnaker 6 | setgid spinnaker 7 | 8 | expect fork 9 | 10 | stop on stopping spinnaker 11 | 12 | exec /opt/kayenta/bin/kayenta 2>&1 >> /var/log/spinnaker/kayenta/kayenta.log & 13 | -------------------------------------------------------------------------------- /kayenta-web/etc/logrotate.d/kayenta: -------------------------------------------------------------------------------- 1 | /var/log/spinnaker/kayenta/kayenta.log { 2 | copytruncate 3 | daily 4 | rotate 10 5 | compress 6 | missingok 7 | create 0644 spinnaker spinnaker 8 | } 9 | -------------------------------------------------------------------------------- /kayenta-web/kayenta-web.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'io.spinnaker.package' 2 | 3 | mainClassName='com.netflix.kayenta.Main' 4 | 5 | configurations.all { 6 | exclude group: 'javax.servlet', module: 'servlet-api' 7 | exclude group: "org.slf4j", module: "slf4j-log4j12" 8 | } 9 | 10 | dependencies { 11 | api project(':kayenta-atlas') 12 | api project(':kayenta-aws') 13 | api project(':kayenta-core') 14 | api project(':kayenta-datadog') 15 | api project(':kayenta-gcs') 16 | api project(':kayenta-google') 17 | api project(':kayenta-blobs') 18 | api project(':kayenta-azure') 19 | api project(':kayenta-graphite') 20 | api project(':kayenta-influxdb') 21 | api project(':kayenta-judge') 22 | api project(':kayenta-newrelic-insights') 23 | api project(':kayenta-objectstore-configbin') 24 | api project(':kayenta-objectstore-memory') 25 | api project(':kayenta-orca') 26 | api project(':kayenta-prometheus') 27 | api project(':kayenta-s3') 28 | api project(':kayenta-signalfx') 29 | api project(':kayenta-sql') 30 | api project(':kayenta-stackdriver') 31 | api project(':kayenta-standalone-canary-analysis') 32 | api project(':kayenta-wavefront') 33 | 34 | api "org.springframework.boot:spring-boot-starter-actuator" 35 | api "io.spinnaker.kork:kork-web" 36 | implementation "io.spinnaker.kork:kork-config" 37 | implementation "io.spinnaker.kork:kork-plugins" 38 | runtimeOnly "io.spinnaker.kork:kork-secrets-aws" 39 | runtimeOnly "io.spinnaker.kork:kork-secrets-gcp" 40 | } 41 | -------------------------------------------------------------------------------- /kayenta-web/lib/systemd/system/kayenta.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kayenta 3 | PartOf=spinnaker.service 4 | 5 | [Service] 6 | ExecStart=/opt/kayenta/bin/kayenta 7 | WorkingDirectory=/opt/kayenta/bin 8 | SuccessExitStatus=143 9 | User=spinnaker 10 | Group=spinnaker 11 | Type=simple 12 | 13 | [Install] 14 | WantedBy=multi-user.target 15 | -------------------------------------------------------------------------------- /kayenta-web/pkg_scripts/postInstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # ubuntu 4 | # check that owner group exists 5 | if [ -z `getent group spinnaker` ]; then 6 | groupadd spinnaker 7 | fi 8 | 9 | # check that user exists 10 | if [ -z `getent passwd spinnaker` ]; then 11 | useradd --gid spinnaker spinnaker -m --home-dir /home/spinnaker 12 | fi 13 | 14 | install --mode=755 --owner=spinnaker --group=spinnaker --directory /var/log/spinnaker/kayenta 15 | -------------------------------------------------------------------------------- /kayenta-web/pkg_scripts/postUninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -rf /var/log/spinnaker/kayenta 4 | -------------------------------------------------------------------------------- /kayenta-web/src/main/java/com/netflix/kayenta/config/ApplicationConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.netflix.kayenta.config; 2 | 3 | import com.netflix.spinnaker.config.PluginsAutoConfiguration; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Import; 8 | import org.springframework.scheduling.annotation.EnableAsync; 9 | import org.springframework.scheduling.annotation.EnableScheduling; 10 | 11 | @Configuration 12 | @Import({ 13 | KayentaConfiguration.class, 14 | WebConfiguration.class, 15 | PluginsAutoConfiguration.class, 16 | }) 17 | @ComponentScan({ 18 | "com.netflix.spinnaker.config", 19 | "com.netflix.spinnaker.endpoint", 20 | }) 21 | @EnableAutoConfiguration 22 | @EnableAsync 23 | @EnableScheduling 24 | public class ApplicationConfiguration {} 25 | -------------------------------------------------------------------------------- /kayenta-web/src/main/java/com/netflix/kayenta/controllers/MetricsServiceDetail.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Netflix, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License") 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.netflix.kayenta.controllers; 18 | 19 | import com.fasterxml.jackson.annotation.JsonInclude; 20 | import java.util.List; 21 | import lombok.*; 22 | 23 | @Builder 24 | @ToString 25 | @NoArgsConstructor 26 | @AllArgsConstructor 27 | @JsonInclude(JsonInclude.Include.NON_NULL) 28 | public class MetricsServiceDetail { 29 | @Getter @NonNull String name; 30 | 31 | @Getter @NonNull String type; 32 | 33 | // See comment in kayenta-core AccountCredentials 34 | @Getter @NonNull List recommendedLocations; 35 | 36 | // See comment in kayenta-core AccountCredentials 37 | @Getter @NonNull List locations; 38 | } 39 | -------------------------------------------------------------------------------- /kayenta-web/src/test/resources/canary-configs/duplicated-metric-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "broken-config", 3 | "applications": [ 4 | "some-application" 5 | ], 6 | "metrics": [ 7 | { 8 | "name": "mem", 9 | "groups": [ 10 | "System" 11 | ], 12 | "analysisConfigurations": {}, 13 | "scopeName": "default" 14 | }, 15 | { 16 | "name": "mem", 17 | "groups": [ 18 | "System" 19 | ], 20 | "analysisConfigurations": {}, 21 | "scopeName": "default" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /lombok.config: -------------------------------------------------------------------------------- 1 | lombok.nonNull.exceptionType = IllegalArgumentException 2 | lombok.accessors.chain = true -------------------------------------------------------------------------------- /scratch/atlas_canary_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MySampleAtlasCanaryConfig", 3 | "description": "Example Automated Canary Analysis (ACA) Configuration using Atlas", 4 | "configVersion": "1.0", 5 | "applications": [ 6 | "myapp" 7 | ], 8 | "judge": { 9 | "name": "dredd-v1.0", 10 | "judgeConfigurations": { 11 | } 12 | }, 13 | "metrics": [ 14 | { 15 | "name": "cpu", 16 | "query": { 17 | "type": "atlas", 18 | "q": "name,randomValue,:eq" 19 | }, 20 | "groups": [ 21 | "system" 22 | ], 23 | "analysisConfigurations": { 24 | } 25 | }, 26 | { 27 | "name": "requests", 28 | "query": { 29 | "type": "atlas", 30 | "q": "name,apache.http.requests,:eq,:sum" 31 | }, 32 | "groups": [ 33 | "requests" 34 | ], 35 | "analysisConfigurations": { 36 | } 37 | } 38 | ], 39 | "classifier": { 40 | "groupWeights": { 41 | "requests": 50.0, 42 | "system": 50.0 43 | }, 44 | "scoreThresholds": { 45 | "pass": 95.0, 46 | "marginal": 75.0 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /scratch/prometheus_canary_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MySamplePrometheusCanaryConfig", 3 | "description": "Example Automated Canary Analysis (ACA) Configuration using Prometheus", 4 | "configVersion": 1.0, 5 | "judge": { 6 | "name": "dredd-v1.0", 7 | "judgeConfigurations": { 8 | } 9 | }, 10 | "metrics": [ 11 | { 12 | "name": "cpu", 13 | "query": { 14 | "type": "prometheus", 15 | "metricName": "node_cpu", 16 | "aggregationPeriod": "60s", 17 | "labelBindings": ["mode=~\"user|system\"", "job=\"node\""], 18 | "sumByFields": ["mode"] 19 | }, 20 | "analysisConfigurations": { 21 | }, 22 | "groups": [ 23 | "system" 24 | ] 25 | } 26 | ], 27 | "classifier": { 28 | "groupWeights": { 29 | "system": 100.0 30 | }, 31 | "scoreThresholds": { 32 | "pass": 95.0, 33 | "marginal": 75.0 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /scratch/stackdriver_canary_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MySampleStackdriverCanaryConfig", 3 | "description": "Example Automated Canary Analysis (ACA) Configuration using Stackdriver", 4 | "configVersion": 1.0, 5 | "applications": [ 6 | "myapp" 7 | ], 8 | "judge": { 9 | "name": "dredd-v1.0", 10 | "judgeConfigurations": { 11 | } 12 | }, 13 | "metrics": [ 14 | { 15 | "name": "cpu", 16 | "query": { 17 | "type": "stackdriver", 18 | "metricType": "compute.googleapis.com/instance/cpu/utilization" 19 | }, 20 | "analysisConfigurations": { 21 | }, 22 | "groups": [ 23 | "system" 24 | ] 25 | } 26 | ], 27 | "classifier": { 28 | "groupWeights": { 29 | "system": 100.0 30 | }, 31 | "scoreThresholds": { 32 | "pass": 95.0, 33 | "marginal": 75.0 34 | } 35 | } 36 | } --------------------------------------------------------------------------------