{"action":"created","comment":{"url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/comments/25757426","id":25757426,"diff_hunk":"@@ -0,0 +1,223 @@\n+/*\n+ * AppInsights-Java\n+ * Copyright (c) Microsoft Corporation\n+ * All rights reserved.\n+ *\n+ * MIT License\n+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this\n+ * software and associated documentation files (the \"\"Software\"\"), to deal in the Software\n+ * without restriction, including without limitation the rights to use, copy, modify, merge,\n+ * publish, distribute, sublicense, and/or sell copies of the Software, and to permit\n+ * persons to whom the Software is furnished to do so, subject to the following conditions:\n+ * The above copyright notice and this permission notice shall be included in all copies or\n+ * substantial portions of the Software.\n+ * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\n+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\n+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n+ * DEALINGS IN THE SOFTWARE.\n+ */\n+\n+package com.microsoft.applicationinsights.internal.perfcounter;\n+\n+import java.util.concurrent.ConcurrentMap;\n+import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ScheduledThreadPoolExecutor;\n+import java.util.concurrent.TimeUnit;\n+import java.util.concurrent.ThreadFactory;\n+\n+import com.microsoft.applicationinsights.TelemetryClient;\n+import com.microsoft.applicationinsights.internal.logger.InternalLogger;\n+import com.microsoft.applicationinsights.internal.shutdown.SDKShutdownActivity;\n+import com.microsoft.applicationinsights.internal.shutdown.Stoppable;\n+import com.microsoft.applicationinsights.internal.util.ThreadPoolUtils;\n+\n+import com.google.common.base.Preconditions;\n+import com.google.common.base.Strings;\n+\n+/**\n+ * The class serves as the container of all {@link com.microsoft.applicationinsights.internal.perfcounter.PerformanceCounter}\n+ *\n+ * If there is a need for a performance counter, the user of this class should create an implementation of that interface\n+ * and then register it in this container.\n+ *\n+ * Note that the container will only start working after the first registration of a Performance Counter.\n+ * That means that setting the timeouts is only relevant if done before the first registration of a Performance Counter.\n+ *\n+ * The container will go through all the registered Performance Counters and will trigger their 'report' method.\n+ * By default the container will start reporting after 5 minutes and will continue doing so every 1 minute.\n+ *\n+ * The user of this class can add (register), remove (unregister) a performance counter while the container is working.\n+ *\n+ * The container will be stopped automatically when the application exists.\n+ */\n+public enum PerformanceCounterContainer implements Stoppable {\n+    INSTANCE;\n+\n+    // By default the container will wait 2 minutes before the collection of performance data.\n+    private final static long START_COLLECTING_INTERVAL_IN_MILLIS = 120000;\n+\n+    // By default the container will collect performance data every 1 minute.\n+    private final static long COLLECTING_INTERVAL_IN_MILLIS = 60000;\n+\n+    private final ConcurrentMap<String, PerformanceCounter> performanceCounters = new ConcurrentHashMap<String, PerformanceCounter>();\n+\n+    private volatile boolean initialized = false;\n+\n+    private long startCollectingIntervalInMillis = START_COLLECTING_INTERVAL_IN_MILLIS;\n+    private long collectingIntervalInMillis = COLLECTING_INTERVAL_IN_MILLIS;\n+\n+    private TelemetryClient telemetryClient;\n+\n+    private ScheduledThreadPoolExecutor threads;\n+\n+    /**\n+     * Registers a {@link com.microsoft.applicationinsights.internal.perfcounter.PerformanceCounter} that can collect data.\n+     * @param performanceCounter The Performance Counter.\n+     */\n+    public void register(PerformanceCounter performanceCounter) {\n+        Preconditions.checkArgument(!Strings.isNullOrEmpty(performanceCounter.getId()), \"performanceCounter's id should be non null, non empty value\");\n+\n+        initialize();\n+        performanceCounters.put(performanceCounter.getId(), performanceCounter);\n+    }\n+\n+    /**\n+     * Un-registers a performance counter.\n+     * @param performanceCounter The Performance Counter.\n+     */\n+    public void unregister(PerformanceCounter performanceCounter) {\n+        unregister(performanceCounter.getId());\n+    }\n+\n+    /**\n+     * Un-registers a performance counter by its id.\n+     * @param id The Performance Counter's id.\n+     */\n+    public void unregister(String id) {\n+        Preconditions.checkArgument(!Strings.isNullOrEmpty(id), \"id should be non null, non empty value\");\n+\n+        performanceCounters.remove(id);\n+    }\n+\n+    /**\n+     * Sets the timeout to wait before the first reporting.\n+     *\n+     * The number must be a positive number\n+     *\n+     * Note that the method will be effective if called before the first call to the 'register' method.\n+     * @param startCollectingIntervalInMillis Timeout to wait before the first collection of performance counters in milliseconds.\n+     */\n+    public void setStartCollectingIntervalInMillis(long startCollectingIntervalInMillis) {\n+        if (startCollectingIntervalInMillis <= 0) {\n+            InternalLogger.INSTANCE.error(\"'%d' is an illegal value is ignored. Must be a positive number\", startCollectingIntervalInMillis);\n+            return;\n+        }\n+\n+        this.startCollectingIntervalInMillis = startCollectingIntervalInMillis;\n+    }\n+\n+    /**\n+     * Gets the timeout in milliseconds that the container will wait before the first collection of Performance Counters.\n+     * @return The first timeout in milliseconds.\n+     */\n+    public long getStartCollectingIntervalInMillis() {\n+        return startCollectingIntervalInMillis;\n+    }\n+\n+    /**\n+     * Sets the timeout to wait between collection of Performance Counters.\n+     *\n+     * The number must be a positive number\n+     *\n+     * Note that the method will be effective if called before the first call to the 'register' method.\n+     * @param collectingIntervalInMillis The timeout to wait between collection of Performance Counters.\n+     */\n+    public void setCollectingIntervalInMillis(long collectingIntervalInMillis) {\n+        if (collectingIntervalInMillis <= 0) {","path":"core/src/main/java/com/microsoft/applicationinsights/internal/perfcounter/PerformanceCounterContainer.java","position":138,"original_position":138,"commit_id":"0f870f1cb5460f750210282c573d60e5d59e982b","original_commit_id":"0f870f1cb5460f750210282c573d60e5d59e982b","user":{"login":"Yonisha","id":10218080,"avatar_url":"https://avatars.githubusercontent.com/u/10218080?v=3","gravatar_id":"","url":"https://api.github.com/users/Yonisha","html_url":"https://github.com/Yonisha","followers_url":"https://api.github.com/users/Yonisha/followers","following_url":"https://api.github.com/users/Yonisha/following{/other_user}","gists_url":"https://api.github.com/users/Yonisha/gists{/gist_id}","starred_url":"https://api.github.com/users/Yonisha/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Yonisha/subscriptions","organizations_url":"https://api.github.com/users/Yonisha/orgs","repos_url":"https://api.github.com/users/Yonisha/repos","events_url":"https://api.github.com/users/Yonisha/events{/privacy}","received_events_url":"https://api.github.com/users/Yonisha/received_events","type":"User","site_admin":false},"body":"I think that we need to enforce a minimal value of at least few seconds, otherwise if a user define 0.0001 we can get like an infinite loop here.","created_at":"2015-03-04T07:59:23Z","updated_at":"2015-03-04T07:59:23Z","html_url":"https://github.com/Microsoft/AppInsights-Java/pull/126#discussion_r25757426","pull_request_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126","_links":{"self":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/comments/25757426"},"html":{"href":"https://github.com/Microsoft/AppInsights-Java/pull/126#discussion_r25757426"},"pull_request":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126"}}},"pull_request":{"url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126","id":30367001,"html_url":"https://github.com/Microsoft/AppInsights-Java/pull/126","diff_url":"https://github.com/Microsoft/AppInsights-Java/pull/126.diff","patch_url":"https://github.com/Microsoft/AppInsights-Java/pull/126.patch","issue_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/126","number":126,"state":"open","locked":false,"title":"Performance Counter adding container","user":{"login":"gupele","id":10058190,"avatar_url":"https://avatars.githubusercontent.com/u/10058190?v=3","gravatar_id":"","url":"https://api.github.com/users/gupele","html_url":"https://github.com/gupele","followers_url":"https://api.github.com/users/gupele/followers","following_url":"https://api.github.com/users/gupele/following{/other_user}","gists_url":"https://api.github.com/users/gupele/gists{/gist_id}","starred_url":"https://api.github.com/users/gupele/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gupele/subscriptions","organizations_url":"https://api.github.com/users/gupele/orgs","repos_url":"https://api.github.com/users/gupele/repos","events_url":"https://api.github.com/users/gupele/events{/privacy}","received_events_url":"https://api.github.com/users/gupele/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-03-03T11:51:50Z","updated_at":"2015-03-04T07:59:23Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c42cb0e6d1b195247a4cd2ab7216d4a3edab0b77","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126/commits","review_comments_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126/comments","review_comment_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/126/comments","statuses_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/statuses/0f870f1cb5460f750210282c573d60e5d59e982b","head":{"label":"Microsoft:features/pc","ref":"features/pc","sha":"0f870f1cb5460f750210282c573d60e5d59e982b","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":27460436,"name":"AppInsights-Java","full_name":"Microsoft/AppInsights-Java","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/AppInsights-Java","description":"Application Insights SDK for Java","fork":false,"url":"https://api.github.com/repos/Microsoft/AppInsights-Java","forks_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/forks","keys_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/teams","hooks_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/events","assignees_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/tags","blobs_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/languages","stargazers_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/subscription","commits_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/merges","archive_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/downloads","issues_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/releases{/id}","created_at":"2014-12-03T00:13:22Z","updated_at":"2015-03-03T22:03:17Z","pushed_at":"2015-03-03T17:45:53Z","git_url":"git://github.com/Microsoft/AppInsights-Java.git","ssh_url":"git@github.com:Microsoft/AppInsights-Java.git","clone_url":"https://github.com/Microsoft/AppInsights-Java.git","svn_url":"https://github.com/Microsoft/AppInsights-Java","homepage":"http://azure.microsoft.com/en-us/services/application-insights/","size":3644,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":6,"forks":0,"open_issues":6,"watchers":0,"default_branch":"master"}},"base":{"label":"Microsoft:master","ref":"master","sha":"722be835379529522e096eccb27ceebd2f5f70ba","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":27460436,"name":"AppInsights-Java","full_name":"Microsoft/AppInsights-Java","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars.githubusercontent.com/u/6154722?v=3","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/AppInsights-Java","description":"Application Insights SDK for Java","fork":false,"url":"https://api.github.com/repos/Microsoft/AppInsights-Java","forks_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/forks","keys_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/teams","hooks_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/events","assignees_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/tags","blobs_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/languages","stargazers_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/subscription","commits_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/merges","archive_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/downloads","issues_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/AppInsights-Java/releases{/id}","created_at":"2014-12-03T00:13:22Z","updated_at":"2015-03-03T22:03:17Z","pushed_at":"2015-03-03T17:45:53Z","git_url":"git://github.com/Microsoft/AppInsights-Java.git","ssh_url":"git@github.com:Microsoft/AppInsights-Java.git","clone_url":"https://github.com/Microsoft/AppInsights-Java.git","svn_url":"https://github.com/Microsoft/AppInsights-Java","homepage":"http://azure.microsoft.com/en-us/services/application-insights/","size":3644,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":6,"forks":0,"open_issues":6,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126"},"html":{"href":"https://github.com/Microsoft/AppInsights-Java/pull/126"},"issue":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/126"},"comments":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/issues/126/comments"},"review_comments":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126/comments"},"review_comment":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/pulls/126/commits"},"statuses":{"href":"https://api.github.com/repos/Microsoft/AppInsights-Java/statuses/0f870f1cb5460f750210282c573d60e5d59e982b"}}}}