Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Adds support for Microsoft Azure Application Insights(AppInsights) as a datastore for Zipkin #27

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
de546ef
Merge pull request #1 from openzipkin/master
praveenbarli May 10, 2017
e4401f2
Adds storage component for Application Insights (AppInsights)
praveenbarli May 10, 2017
3b4bc0a
Merge remote-tracking branch 'origin/master' into addai
Jun 23, 2017
5184e7c
Merge pull request #2 from SergeyKanzhelev/addai
praveenbarli Jun 23, 2017
b894c0b
parent verions updated from0.1.6 to 0.1.7
praveenbarli Jun 26, 2017
f9912ea
parent verions updated from0.1.6 to 0.1.7
praveenbarli Jun 26, 2017
c563faf
Merge branch 'createautoconfigureappinsightmodule' of https://github.…
praveenbarli Jun 26, 2017
78a8ebd
data model changes to add name, id and dependency for sr annotaiton
praveenbarli Jun 26, 2017
219c4f1
data model changes to add name, id and dependency for sr annotaiton
praveenbarli Jun 26, 2017
71d4cec
Merge branch 'writetoaidatamodel' of https://github.com/praveenbarli/…
praveenbarli Jun 27, 2017
735e056
removed unused refs
praveenbarli Jun 27, 2017
249284b
removed appinsights config, appinsights-web pkg
praveenbarli Jun 27, 2017
607f59c
set operation id to hex val of traceid's, duration in millis
praveenbarli Jun 29, 2017
ab7fc99
Merge pull request #5 from praveenbarli/writetoaidatamodel
praveenbarli Jun 29, 2017
795b03a
readme.md
Jun 23, 2017
98cfa3d
update spacing in configuraiton file
Jun 26, 2017
ae56314
fix script
Jun 26, 2017
534f785
few things
Jun 30, 2017
2d16b45
Merge pull request #3 from SergeyKanzhelev/addai
praveenbarli Jun 30, 2017
a63bf61
add zipkin span in json as custom property to requests/dependencies t…
praveenbarli Jul 3, 2017
40950a2
Merge pull request #6 from praveenbarli/addzipkinspanproperty
praveenbarli Jul 3, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -33,6 +35,7 @@

<modules>
<module>collector-eventhub</module>
<module>storage-applicationinsights</module>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the difference between collector and storage? Should we have Application Insights collector AND storage. So collection part can be used separately from the storage?

Copy link
Contributor Author

@praveenbarli praveenbarli Jun 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collector is the transport protocol(default Http) you listen on ... for receiving spans. Right now we are using Http - so, I guess we might not have a separate AI collector unless you have a better business case where AI collector helps.
You can directly hit your storage with Spans if that is your question. It is fine as long as Zipkin REST API gets the right data while reading.
Collectors like Eventhub could have many clients other than storage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can collector be used in-process? So we do not need a sidecar container hosting it? Also it looks to me this is a regular setup. Like here:

Production configuration

  • Numerous collectors zipkin collectors per data centre – no UI enabled
  • One zipkin UI server per data centre – firewalled and hidden behind an apache web server to provide authentication and auditing. Not accessible for span collector service

</modules>
<dependencyManagement>
<dependencies>
Expand Down
84 changes: 84 additions & 0 deletions autoconfigure/storage-applicationinsights/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright 2017 The OpenZipkin Authors

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the License for the specific language governing permissions and limitations under
the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.zipkin.azure</groupId>
<version>0.1.6-SNAPSHOT</version>
<artifactId>zipkin-autoconfigure-parent</artifactId>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>zipkin-autoconfigure-storage-applicationinsights</artifactId>
<name>Zipkin Auto Configuration: Azure Application Insights Storage</name>

<properties>
<main.basedir>${project.basedir}/../..</main.basedir>
</properties>

<dependencies>
<dependency>
<groupId>io.zipkin.azure</groupId>
<artifactId>zipkin-storage-applicationinsights</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!--<version>3.8.1</version>-->
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
<!--<dependency>-->
<!--<groupId>io.zipkin.brave</groupId>-->
<!--<artifactId>brave-core</artifactId>-->
<!--<version>${brave.version}</version>-->
<!--<optional>true</optional>-->
<!--</dependency>-->
</dependencies>
<!--to do: got to check build contents - got it from autoconfigure-collector-eventhub-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<layout>MODULE</layout>
<classifier>module</classifier>
<!-- https://github.com/spring-projects/spring-boot/issues/3426 transitive exclude doesn't work -->
<excludeGroupIds>
io.zipkin.java,org.springframework.boot,org.springframework,commons-codec,com.fasterxml.jackson.core,com.fasterxml.jackson.dataformat,org.apache.httpcomponents,commons-logging,joda-time,software.amazon.ion
</excludeGroupIds>
<!-- already packaged in zipkin-server -->
<excludeArtifactIds>jmespath-java</excludeArtifactIds>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright 2017 The OpenZipkin Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package zipkin.autoconfigure.storage.applicationinsights;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import zipkin.storage.StorageComponent;
import zipkin.storage.applicationinsights.ApplicationInsightsStorage;
import java.util.concurrent.Executor;

/**
* This storage accepts ApplicationInsights logs in a specified category. Each log entry is expected
* to contain a single span, which is TBinaryProtocol big-endian, then base64 encoded. Decoded spans
* are stored asynchronously.
*/
@Configuration
@EnableConfigurationProperties(ZipkinApplicationInsightsStorageProperties.class)
@ConditionalOnProperty(name = "zipkin.storage.type", havingValue = "applicationinsights")
@ConditionalOnMissingBean(StorageComponent.class)
public class ZipkinApplicationInsightsStorageAutoConfiguration {

@Bean @ConditionalOnMissingBean(Executor.class) Executor executor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setThreadNamePrefix("ZipkinApplicationInsightsStorage-");
executor.initialize();
return executor;
}

@Bean StorageComponent storage(Executor executor,
ZipkinApplicationInsightsStorageProperties properties,
@Value("${zipkin.storage.strict-trace-id:true}") boolean strictTraceId) {
return ApplicationInsightsStorage.builder()
.strictTraceId(strictTraceId)
.instrumentationKey(properties.getInstrumentationKey())
.applicationId(properties.getApplicationId())
.apikey(properties.getApiKey())
.executor(executor)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright 2017 The OpenZipkin Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package zipkin.autoconfigure.storage.applicationinsights;

import java.util.concurrent.TimeUnit;
import org.springframework.boot.context.properties.ConfigurationProperties;
import zipkin.storage.applicationinsights.ApplicationInsightsStorage;

@ConfigurationProperties("zipkin.storage.applicationinsights")
public class ZipkinApplicationInsightsStorageProperties {

private String instrumentationKey;
private String applicationId;
private String apiKey;

public String getInstrumentationKey() {
return instrumentationKey;
}

public void setInstrumentationKey(String key) {
this.instrumentationKey = key;
}

public String getApplicationId() {
return applicationId;
}

public void setApplicationId(String key) {
this.applicationId = key;
}

public String getApiKey() {
return apiKey;
}

public void setApiKey(String key) {
this.apiKey = key;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
zipkin.autoconfigure.storage.applicationinsights.ZipkinApplicationInsightsStorageAutoConfiguration
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# When enabled, this allows shorter env properties (ex -Dspring.profiles.active=applicationinsights)
zipkin:
storage:
applicationinsights:
instrumentationKey: ${AI_INSTRUMENTATION_KEY:}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it's a section applicationinsights - why we need to prefix it with AI_?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is readable here in config file.. but during actual configuration user jus sets AI_INSTRU... and it would be much clearer to have prefix.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

environment variable for instrumentation key that we typically use is APPINSIGHTS_INSTRUMENTATIONKEY https://github.com/Microsoft/ApplicationInsights-dotnet/blob/151509eac5e23fcbd09f3a8989a35d1099703957/src/Core/Managed/Shared/Extensibility/Implementation/TelemetryConfigurationFactory.cs#L22

It is not ideal as it uses a wrong name appinishgts, but it is what we use everywhere

Copy link
Contributor Author

@praveenbarli praveenbarli Jun 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change it to APPINSIGHTS.. If thats norm.... i just thought AI_IN... will make the key shorter..and in power shell I often type so less work :)

applicationId: ${AI_APPLICATION_ID:}
apiKey: ${AI_API_KEY:}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how fast are you running to the query limit? Using Azure Active Directory authentication may eliminate this problem, but may be hard to implement. Just a thought in case you have an idea how to fix it

Copy link
Contributor Author

@praveenbarli praveenbarli Jun 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran few thousands and didn't face much issues. For higher loads .. I am thinking of rotating API_Keys as a solution ..but would like to know about AAD.

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Copyright 2017 The OpenZipkin Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package zipkin.storage.applicationinsights;

import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import zipkin.autoconfigure.storage.applicationinsights.ZipkinApplicationInsightsStorageAutoConfiguration;
import zipkin.autoconfigure.storage.applicationinsights.ZipkinApplicationInsightsStorageProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;

public class ZipkinApplicationInsightsStorageAutoConfigurationTest {
@Rule
public ExpectedException thrown = ExpectedException.none();

AnnotationConfigApplicationContext context;

@After
public void close() {
if (context != null) {
context.close();
}
}

@Test
public void doesntProvidesStorageComponent_whenStorageTypeNotApplicationInsights() {
context = new AnnotationConfigApplicationContext();
addEnvironment(context, "zipkin.storage.type:elasticsearch");
context.register(PropertyPlaceholderAutoConfiguration.class,
ZipkinApplicationInsightsStorageAutoConfiguration.class);
context.refresh();

thrown.expect(NoSuchBeanDefinitionException.class);
context.getBean(ApplicationInsightsStorage.class);
}

@Test
public void providesStorageComponent_whenStorageTypeApplicationInsights() {
context = new AnnotationConfigApplicationContext();
addEnvironment(context, "zipkin.storage.type:applicationinsights");
context.register(PropertyPlaceholderAutoConfiguration.class,
ZipkinApplicationInsightsStorageAutoConfiguration.class);
context.refresh();

assertThat(context.getBean(ApplicationInsightsStorage.class)).isNotNull();
}

@Test
public void canOverridesProperty_InstrumentationKey() {
context = new AnnotationConfigApplicationContext();
addEnvironment(context,
"zipkin.storage.type:applicationinsights",
"zipkin.storage.applicationinsights.instrumentationKey:xyz",
"zipkin.storage.applicationinsights.applicationId:abc",
"zipkin.storage.applicationinsights.apiKey:mnm"
);
context.register(PropertyPlaceholderAutoConfiguration.class,
ZipkinApplicationInsightsStorageAutoConfiguration.class);
context.refresh();

assertThat(
context.getBean(ZipkinApplicationInsightsStorageProperties.class).getInstrumentationKey())
.isEqualTo("xyz");
}
}
8 changes: 6 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>io.zipkin.azure</groupId>
Expand All @@ -24,6 +26,7 @@

<modules>
<module>collector</module>
<module>storage</module>
<module>autoconfigure</module>
</modules>

Expand Down Expand Up @@ -63,7 +66,8 @@
<scm>
<url>https://github.com/openzipkin/zipkin-azure</url>
<connection>scm:git:https://github.com/openzipkin/zipkin-azure.git</connection>
<developerConnection>scm:git:https://github.com/openzipkin/zipkin-azure.git</developerConnection>
<developerConnection>scm:git:https://github.com/openzipkin/zipkin-azure.git
</developerConnection>
<tag>HEAD</tag>
</scm>

Expand Down
Loading