1
#pragma once
2

            
3
#include "envoy/data/accesslog/v3/accesslog.pb.h"
4
#include "envoy/extensions/access_loggers/stats/v3/stats.pb.h"
5
#include "envoy/stats/stats.h"
6
#include "envoy/stats/tag.h"
7

            
8
#include "source/common/matcher/matcher.h"
9
#include "source/extensions/access_loggers/common/access_log_base.h"
10
#include "source/extensions/matching/actions/transform_stat/transform_stat.h"
11

            
12
namespace Envoy {
13
namespace Extensions {
14
namespace AccessLoggers {
15
namespace StatsAccessLog {
16

            
17
class StatsAccessLog : public AccessLoggers::Common::ImplBase {
18
public:
19
  StatsAccessLog(const envoy::extensions::access_loggers::stats::v3::Config& config,
20
                 Server::Configuration::GenericFactoryContext& context,
21
                 AccessLog::FilterPtr&& filter,
22
                 const std::vector<Formatter::CommandParserPtr>& command_parsers);
23

            
24
private:
25
  // AccessLoggers::Common::ImplBase
26
  void emitLog(const Formatter::Context& context,
27
               const StreamInfo::StreamInfo& stream_info) override;
28

            
29
  // `emitLog` is called concurrently from different works. Move all the logic into a const function
30
  // to ensure there are no data races in mutation of class members.
31
  void emitLogConst(const Formatter::Context& context,
32
                    const StreamInfo::StreamInfo& stream_info) const;
33

            
34
  class DynamicTag {
35
  public:
36
    DynamicTag(const envoy::extensions::access_loggers::stats::v3::Config::Tag& tag_cfg,
37
               Envoy::Stats::StatNamePool& pool,
38
               const std::vector<Formatter::CommandParserPtr>& commands,
39
               Server::Configuration::GenericFactoryContext& context);
40
3
    DynamicTag(DynamicTag&&) = default;
41

            
42
    const Envoy::Stats::StatName name_;
43
    Formatter::FormatterPtr value_formatter_;
44
    Matcher::MatchTreeSharedPtr<Envoy::Stats::StatTagMatchingData> rules_;
45
  };
46

            
47
  // The construction of NameAndTags can only be made at initialization time because it needs to
48
  // intern tag names into StatNames via the StatNamePool in the main thread.
49
  class NameAndTags {
50
  public:
51
    NameAndTags(const envoy::extensions::access_loggers::stats::v3::Config::Stat& cfg,
52
                Envoy::Stats::StatNamePool& pool,
53
                const std::vector<Formatter::CommandParserPtr>& commands,
54
                Server::Configuration::GenericFactoryContext& context);
55

            
56
    struct TagsResult {
57
      Envoy::Stats::StatNameTagVector tags_;
58
      std::vector<Envoy::Stats::StatNameDynamicStorage> dynamic_storage_;
59
      bool dropped_;
60
    };
61
    TagsResult tags(const Formatter::Context& context, const StreamInfo::StreamInfo& stream_info,
62
                    Envoy::Stats::Scope& scope) const;
63

            
64
    Envoy::Stats::StatName name_;
65
    std::vector<DynamicTag> dynamic_tags_;
66
  };
67

            
68
  struct Histogram {
69
    NameAndTags stat_;
70
    Envoy::Stats::Histogram::Unit unit_;
71
    Formatter::FormatterProviderPtr value_formatter_;
72
  };
73

            
74
  struct Counter {
75
    NameAndTags stat_;
76
    Formatter::FormatterProviderPtr value_formatter_;
77
    uint64_t value_fixed_;
78
  };
79

            
80
  struct Gauge {
81
    enum class OperationType {
82
      SET,
83
      PAIRED_ADD,
84
      PAIRED_SUBTRACT,
85
    };
86

            
87
    NameAndTags stat_;
88
    Formatter::FormatterProviderPtr value_formatter_;
89
    uint64_t value_fixed_;
90
    absl::InlinedVector<std::pair<envoy::data::accesslog::v3::AccessLogType, OperationType>, 2>
91
        operations_;
92
  };
93

            
94
  void emitLogForGauge(const Gauge& gauge, const Formatter::Context& context,
95
                       const StreamInfo::StreamInfo& stream_info) const;
96

            
97
  const Stats::ScopeSharedPtr scope_;
98
  Stats::StatNamePool stat_name_pool_;
99

            
100
  const std::vector<Histogram> histograms_;
101
  const std::vector<Counter> counters_;
102
  const std::vector<Gauge> gauges_;
103
};
104

            
105
} // namespace StatsAccessLog
106
} // namespace AccessLoggers
107
} // namespace Extensions
108
} // namespace Envoy