class StreamsMetricsImpl implements StreamsMetrics {

    public final Sensor storeLevelSensor(final String taskId,
                                         final String storeName,
                                         final String sensorName,
                                         final RecordingLevel recordingLevel,
                                         final Sensor... parents) {
        final String key = storeSensorPrefix(Thread.currentThread().getName(), taskId, storeName);
        final String fullSensorName = key + SENSOR_NAME_DELIMITER + sensorName;
        final Sensor sensor = metrics.getSensor(fullSensorName);
        if (sensor == null) {
            // since the keys in the map storeLevelSensors contain the name of the current thread and threads only
            // access keys in which their name is contained, the value in the maps do not need to be thread safe
            // and we can use a LinkedList here.
            // TODO: In future, we could use thread local maps since each thread will exclusively access the set of keys
            //  that contain its name. Similar is true for the other metric levels. Thread-level metrics need some
            //  special attention, since they are created before the thread is constructed. The creation of those
            //  metrics could be moved into the run() method of the thread.
            storeLevelSensors.computeIfAbsent(key, ignored -> new LinkedList<>()).push(fullSensorName);
            return metrics.sensor(fullSensorName, recordingLevel, parents);
        }
        return sensor;
    }

    public  StreamsMetricsImpl(final Metrics metrics,
                              final String clientId,
                              final String builtInMetricsVersion,
                              final Time time);

}