public static Sensor StreamsAppSensor(
            string applicationId,
            string topologyDescription,
            Func <int> stateStreamFunc,
            Func <int> streamThreadsFunc,
            StreamMetricsRegistry metricsRegistry)
        {
            var sensor = metricsRegistry.ClientLevelSensor(
                APP_INFO,
                APP_INFO_DESCRIPTION,
                MetricsRecordingLevel.INFO);
            var tags = metricsRegistry.ClientTags();

            tags.Add(APPLICATION_ID, applicationId);

            var tagsVersion = new Dictionary <string, string>(tags);

            tagsVersion.Add(VERSION, VERSION_FROM_ASSEMBLY);
            sensor.AddImmutableMetric(
                new MetricName(
                    VERSION,
                    StreamMetricsRegistry.CLIENT_LEVEL_GROUP,
                    VERSION_DESCRIPTION,
                    tagsVersion), VERSION_FROM_ASSEMBLY);

            sensor.AddImmutableMetric(
                new MetricName(
                    APPLICATION_ID,
                    StreamMetricsRegistry.CLIENT_LEVEL_GROUP,
                    APPLICATION_ID_DESCRIPTION,
                    tags), applicationId);

            var tagsTopo = new Dictionary <string, string>(tags);

            tagsTopo.Add(TOPOLOGY_DESCRIPTION, topologyDescription);
            sensor.AddImmutableMetric(
                new MetricName(
                    TOPOLOGY_DESCRIPTION,
                    StreamMetricsRegistry.CLIENT_LEVEL_GROUP,
                    TOPOLOGY_DESCRIPTION_DESCRIPTION,
                    tagsTopo), topologyDescription);

            sensor.AddProviderMetric(
                new MetricName(
                    STATE,
                    StreamMetricsRegistry.CLIENT_LEVEL_GROUP,
                    STATE_DESCRIPTION,
                    tags), stateStreamFunc);

            sensor.AddProviderMetric(
                new MetricName(
                    STREAM_THREADS,
                    StreamMetricsRegistry.CLIENT_LEVEL_GROUP,
                    STREAM_THREADS_DESCRIPTION,
                    tags), streamThreadsFunc);

            return(sensor);
        }