blob: 2bd667615d19f6fba284f0cfed56bd126215a426 [file] [log] [blame]
// Copyright 2017, OpenCensus 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.
#ifndef OPENCENSUS_STATS_INTERNAL_STATS_MANAGER_H_
#define OPENCENSUS_STATS_INTERNAL_STATS_MANAGER_H_
#include <memory>
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "opencensus/common/internal/stats_object.h"
#include "opencensus/stats/distribution.h"
#include "opencensus/stats/internal/delta_producer.h"
#include "opencensus/stats/internal/measure_data.h"
#include "opencensus/stats/internal/view_data_impl.h"
#include "opencensus/stats/measure.h"
#include "opencensus/stats/view_descriptor.h"
#include "opencensus/tags/tag_key.h"
#include "opencensus/tags/tag_map.h"
namespace opencensus {
namespace stats {
// StatsManager is a singleton class that stores data for active views, adding
// values from Record() events.
class StatsManager final {
public:
// ViewInformation stores part of the data of a ViewDescriptor
// (measure, aggregation, and columns), along with the data for the view.
// ViewInformation is thread-compatible; its non-const data is protected by an
// external mutex, which most non-const member functions require holding.
class ViewInformation {
public:
ViewInformation(const ViewDescriptor& descriptor, absl::Mutex* mu);
// Returns true if this ViewInformation can be used to provide data for
// 'descriptor' (i.e. shares measure, aggregation, aggregation window, and
// columns; this does not compare view name and description).
bool Matches(const ViewDescriptor& descriptor) const;
int num_consumers() const;
// Increments the consumer count. Requires holding *mu_.
void AddConsumer();
// Decrements the consumer count and returns the resulting count. Requires
// holding *mu_.
int RemoveConsumer();
// Adds 'data' under 'tags' as of 'now'. Requires holding *mu_;
void MergeMeasureData(const opencensus::tags::TagMap& tags,
const MeasureData& data, absl::Time now);
// Retrieves a copy of the data.
std::unique_ptr<ViewDataImpl> GetData() ABSL_LOCKS_EXCLUDED(*mu_);
const ViewDescriptor& view_descriptor() const { return descriptor_; }
private:
const ViewDescriptor descriptor_;
absl::Mutex* const mu_; // Not owned.
// The number of View objects backed by this ViewInformation, for
// reference-counted GC.
int num_consumers_ ABSL_GUARDED_BY(*mu_) = 1;
// Possible types of stored data.
enum class DataType { kDouble, kUint64, kDistribution, kInterval };
static DataType DataTypeForDescriptor(const ViewDescriptor& descriptor);
ViewDataImpl data_ ABSL_GUARDED_BY(*mu_);
};
public:
static StatsManager* Get();
// Merges all data from 'delta' at the present time.
void MergeDelta(const Delta& delta) ABSL_LOCKS_EXCLUDED(mu_);
// Adds a measure--this is necessary for views to be added under that measure.
template <typename MeasureT>
void AddMeasure(Measure<MeasureT> measure) ABSL_LOCKS_EXCLUDED(mu_);
// Returns a handle that can be used to retrieve data for 'descriptor' (which
// may point to a new or reused ViewInformation).
ViewInformation* AddConsumer(const ViewDescriptor& descriptor)
ABSL_LOCKS_EXCLUDED(mu_);
// Removes a consumer from the ViewInformation 'handle', and deletes it if
// that was the last consumer.
void RemoveConsumer(ViewInformation* handle) ABSL_LOCKS_EXCLUDED(mu_);
private:
// MeasureInformation stores all ViewInformation objects for a given measure.
class MeasureInformation {
public:
explicit MeasureInformation(absl::Mutex* mu) : mu_(mu) {}
// Merges measure_data into all views under this measure. Requires holding
// *mu_;
void MergeMeasureData(const opencensus::tags::TagMap& tags,
const MeasureData& data, absl::Time now);
ViewInformation* AddConsumer(const ViewDescriptor& descriptor);
void RemoveView(const ViewInformation* handle);
private:
absl::Mutex* const mu_; // Not owned.
// View objects hold a pointer to ViewInformation directly, so we do not
// need fast lookup--lookup is only needed for view removal.
std::vector<std::unique_ptr<ViewInformation>> views_ ABSL_GUARDED_BY(*mu_);
};
// TODO: PERF: Global synchronization is only needed for adding or
// removing measures--we can reduce recording contention by claiming a reader
// lock on mu_ and a writer lock on a measure-specific mutex.
mutable absl::Mutex mu_;
// All registered measures.
std::vector<MeasureInformation> measures_ ABSL_GUARDED_BY(mu_);
};
extern template void StatsManager::AddMeasure(MeasureDouble measure);
extern template void StatsManager::AddMeasure(MeasureInt64 measure);
} // namespace stats
} // namespace opencensus
#endif // OPENCENSUS_STATS_INTERNAL_STATS_MANAGER_H_