/* * ApplicationInsights-Java * Copyright (c) Microsoft Corporation * All rights reserved. * * MIT License * Permission is hereby granted, free of charge, to any person obtaining a copy of this * software and associated documentation files (the ""Software""), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or * substantial portions of the Software. * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ package com.microsoft.applicationinsights.extensibility.initializer.docker; import com.microsoft.applicationinsights.TelemetryConfiguration; import com.microsoft.applicationinsights.extensibility.TelemetryInitializer; import com.microsoft.applicationinsights.extensibility.initializer.docker.internal.*; import com.microsoft.applicationinsights.internal.logger.InternalLogger; import com.microsoft.applicationinsights.internal.util.LocalStringsUtils; import com.microsoft.applicationinsights.telemetry.Telemetry; import com.microsoft.applicationinsights.telemetry.TelemetryContext; import java.io.IOException; import java.util.concurrent.ConcurrentMap; // Created by yonisha on 7/29/2015. /** * * * This initializer is required for Docker awareness. * The initializer has two goals: * 1) Identify Docker context file injected by Application Insight for Docker container and initialize * telemetries with Docker context. * 2) Write SDK context file which enables the Application Insights for Docker container to discover containers with * integrated SDK, and stop sending performance counters in that case (SDK provides OOB performance counters). */ public class DockerContextInitializer implements TelemetryInitializer { private FileFactory fileFactory; private DockerContextPoller dockerContextPoller; private boolean sdkInfoFileWritten = false; protected DockerContextInitializer(FileFactory fileFactory, DockerContextPoller dockerContextPoller) { this.fileFactory = fileFactory; this.dockerContextPoller = dockerContextPoller; this.dockerContextPoller.start(); } /** * Constructs new @DockerContextInitializer. * The constructor start a dedicated thread that periodically checks if a context file exists, and if so, updates * the docker context. */ public DockerContextInitializer() { this(new FileFactory(), new DockerContextPoller(Constants.AI_SDK_DIRECTORY)); } /** * Initialize the given telemetry with the Docker context. * @param telemetry A Telemetry to initialize. */ @Override public void initialize(Telemetry telemetry) { DockerContext dockerContext; if (!sdkInfoFileWritten) { synchronized (this) { if (!sdkInfoFileWritten) { writeSDKInfoFile(); sdkInfoFileWritten = true; } } } if (dockerContextPoller.isCompleted() && (dockerContext = dockerContextPoller.getDockerContext()) != null) { TelemetryContext context = telemetry.getContext(); // We always set the device ID, since by default it is represented by a GUID inside Docker container. String containerName = dockerContext.getProperties().get(Constants.DOCKER_CONTAINER_NAME_PROPERTY_KEY); context.getDevice().setId(containerName); // If telemetry already initialized with Docker properties, we don't overwrite it. if (!LocalStringsUtils.isNullOrEmpty(context.getProperties().get(Constants.DOCKER_HOST_PROPERTY_KEY))) { return; } ConcurrentMap<String, String> properties = context.getProperties(); properties.putAll(dockerContext.getProperties()); } } private void writeSDKInfoFile() { String sdkInfoFilePath = String.format("%s/%s", Constants.AI_SDK_DIRECTORY, Constants.AI_SDK_INFO_FILENAME); String instrumentationKey = TelemetryConfiguration.getActive().getInstrumentationKey(); String sdkInfo = String.format(Constants.AI_SDK_INFO_FILE_CONTENT_TEMPLATE, instrumentationKey); try { fileFactory.create(sdkInfoFilePath, sdkInfo); } catch (IOException e) { InternalLogger.INSTANCE.error("Failed to write SDK info file for Docker awareness. Error: " + e.getMessage()); } } }