LCOV - code coverage report
Current view: top level - source/common/access_log - access_log_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 1 3 33.3 %
Date: 2024-01-05 06:35:25 Functions: 1 3 33.3 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <string>
       5             : #include <vector>
       6             : 
       7             : #include "envoy/access_log/access_log.h"
       8             : #include "envoy/access_log/access_log_config.h"
       9             : #include "envoy/common/random_generator.h"
      10             : #include "envoy/config/accesslog/v3/accesslog.pb.h"
      11             : #include "envoy/config/typed_config.h"
      12             : #include "envoy/runtime/runtime.h"
      13             : #include "envoy/type/v3/percent.pb.h"
      14             : 
      15             : #include "source/common/common/matchers.h"
      16             : #include "source/common/common/utility.h"
      17             : #include "source/common/config/utility.h"
      18             : #include "source/common/formatter/http_specific_formatter.h"
      19             : #include "source/common/grpc/status.h"
      20             : #include "source/common/http/header_utility.h"
      21             : #include "source/common/protobuf/protobuf.h"
      22             : 
      23             : #include "absl/container/node_hash_set.h"
      24             : #include "absl/hash/hash.h"
      25             : 
      26             : namespace Envoy {
      27             : namespace AccessLog {
      28             : 
      29             : /**
      30             :  * Access log filter factory that reads from proto.
      31             :  */
      32             : class FilterFactory {
      33             : public:
      34             :   /**
      35             :    * Read a filter definition from proto and instantiate a concrete filter class.
      36             :    */
      37             :   static FilterPtr fromProto(const envoy::config::accesslog::v3::AccessLogFilter& config,
      38             :                              Server::Configuration::FactoryContext& context);
      39             : };
      40             : 
      41             : /**
      42             :  * Base implementation of an access log filter that performs comparisons.
      43             :  */
      44             : class ComparisonFilter : public Filter {
      45             : protected:
      46             :   ComparisonFilter(const envoy::config::accesslog::v3::ComparisonFilter& config,
      47             :                    Runtime::Loader& runtime);
      48             : 
      49             :   bool compareAgainstValue(uint64_t lhs) const;
      50             : 
      51             :   envoy::config::accesslog::v3::ComparisonFilter config_;
      52             :   Runtime::Loader& runtime_;
      53             : };
      54             : 
      55             : /**
      56             :  * Filter on response status code.
      57             :  */
      58             : class StatusCodeFilter : public ComparisonFilter {
      59             : public:
      60             :   StatusCodeFilter(const envoy::config::accesslog::v3::StatusCodeFilter& config,
      61             :                    Runtime::Loader& runtime)
      62           0 :       : ComparisonFilter(config.comparison(), runtime) {}
      63             : 
      64             :   // AccessLog::Filter
      65             :   bool evaluate(const Formatter::HttpFormatterContext& context,
      66             :                 const StreamInfo::StreamInfo& info) const override;
      67             : };
      68             : 
      69             : /**
      70             :  * Filter on total request/response duration.
      71             :  */
      72             : class DurationFilter : public ComparisonFilter {
      73             : public:
      74             :   DurationFilter(const envoy::config::accesslog::v3::DurationFilter& config,
      75             :                  Runtime::Loader& runtime)
      76           0 :       : ComparisonFilter(config.comparison(), runtime) {}
      77             : 
      78             :   // AccessLog::Filter
      79             :   bool evaluate(const Formatter::HttpFormatterContext& context,
      80             :                 const StreamInfo::StreamInfo& info) const override;
      81             : };
      82             : 
      83             : /**
      84             :  * Base operator filter, compose other filters with operation
      85             :  */
      86             : class OperatorFilter : public Filter {
      87             : public:
      88             :   OperatorFilter(
      89             :       const Protobuf::RepeatedPtrField<envoy::config::accesslog::v3::AccessLogFilter>& configs,
      90             :       Server::Configuration::FactoryContext& context);
      91             : 
      92             : protected:
      93             :   std::vector<FilterPtr> filters_;
      94             : };
      95             : 
      96             : /**
      97             :  * *And* operator filter, apply logical *and* operation to all of the sub filters.
      98             :  */
      99             : class AndFilter : public OperatorFilter {
     100             : public:
     101             :   AndFilter(const envoy::config::accesslog::v3::AndFilter& config,
     102             :             Server::Configuration::FactoryContext& context);
     103             : 
     104             :   // AccessLog::Filter
     105             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     106             :                 const StreamInfo::StreamInfo& info) const override;
     107             : };
     108             : 
     109             : /**
     110             :  * *Or* operator filter, apply logical *or* operation to all of the sub filters.
     111             :  */
     112             : class OrFilter : public OperatorFilter {
     113             : public:
     114             :   OrFilter(const envoy::config::accesslog::v3::OrFilter& config,
     115             :            Server::Configuration::FactoryContext& context);
     116             : 
     117             :   // AccessLog::Filter
     118             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     119             :                 const StreamInfo::StreamInfo& info) const override;
     120             : };
     121             : 
     122             : /**
     123             :  * Filter out health check requests.
     124             :  */
     125             : class NotHealthCheckFilter : public Filter {
     126             : public:
     127          70 :   NotHealthCheckFilter() = default;
     128             : 
     129             :   // AccessLog::Filter
     130             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     131             :                 const StreamInfo::StreamInfo& info) const override;
     132             : };
     133             : 
     134             : /**
     135             :  * Filter traceable requests.
     136             :  */
     137             : class TraceableRequestFilter : public Filter {
     138             : public:
     139             :   // AccessLog::Filter
     140             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     141             :                 const StreamInfo::StreamInfo& info) const override;
     142             : };
     143             : 
     144             : /**
     145             :  * Filter that uses a runtime feature key to check if the log should be written.
     146             :  */
     147             : class RuntimeFilter : public Filter {
     148             : public:
     149             :   RuntimeFilter(const envoy::config::accesslog::v3::RuntimeFilter& config, Runtime::Loader& runtime,
     150             :                 Random::RandomGenerator& random);
     151             : 
     152             :   // AccessLog::Filter
     153             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     154             :                 const StreamInfo::StreamInfo& info) const override;
     155             : 
     156             : private:
     157             :   Runtime::Loader& runtime_;
     158             :   Random::RandomGenerator& random_;
     159             :   const std::string runtime_key_;
     160             :   const envoy::type::v3::FractionalPercent percent_;
     161             :   const bool use_independent_randomness_;
     162             : };
     163             : 
     164             : /**
     165             :  * Filter based on headers.
     166             :  */
     167             : class HeaderFilter : public Filter {
     168             : public:
     169             :   HeaderFilter(const envoy::config::accesslog::v3::HeaderFilter& config);
     170             : 
     171             :   // AccessLog::Filter
     172             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     173             :                 const StreamInfo::StreamInfo& info) const override;
     174             : 
     175             : private:
     176             :   const Http::HeaderUtility::HeaderDataPtr header_data_;
     177             : };
     178             : 
     179             : /**
     180             :  * Filter requests that had a response with an Envoy response flag set.
     181             :  */
     182             : class ResponseFlagFilter : public Filter {
     183             : public:
     184             :   ResponseFlagFilter(const envoy::config::accesslog::v3::ResponseFlagFilter& config);
     185             : 
     186             :   // AccessLog::Filter
     187             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     188             :                 const StreamInfo::StreamInfo& info) const override;
     189             : 
     190             : private:
     191             :   uint64_t configured_flags_{};
     192             : };
     193             : 
     194             : /**
     195             :  * Filters requests that have a response with a gRPC status. Because the gRPC protocol does not
     196             :  * guarantee a gRPC status code, if a gRPC status code is not available, then the filter will infer
     197             :  * the gRPC status code from an HTTP status code if available.
     198             :  */
     199             : class GrpcStatusFilter : public Filter {
     200             : public:
     201             :   using GrpcStatusHashSet =
     202             :       absl::node_hash_set<Grpc::Status::GrpcStatus, absl::Hash<Grpc::Status::GrpcStatus>>;
     203             : 
     204             :   GrpcStatusFilter(const envoy::config::accesslog::v3::GrpcStatusFilter& config);
     205             : 
     206             :   // AccessLog::Filter
     207             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     208             :                 const StreamInfo::StreamInfo& info) const override;
     209             : 
     210             : private:
     211             :   GrpcStatusHashSet statuses_;
     212             :   bool exclude_;
     213             : 
     214             :   /**
     215             :    * Converts a Protobuf representation of a gRPC status into the equivalent code version of a gRPC
     216             :    * status.
     217             :    */
     218             :   Grpc::Status::GrpcStatus
     219             :   protoToGrpcStatus(envoy::config::accesslog::v3::GrpcStatusFilter::Status status) const;
     220             : };
     221             : 
     222             : /**
     223             :  * Filters requests based on access log type
     224             :  */
     225             : class LogTypeFilter : public Filter {
     226             : public:
     227             :   using LogTypeHashSet = absl::flat_hash_set<AccessLogType>;
     228             : 
     229             :   LogTypeFilter(const envoy::config::accesslog::v3::LogTypeFilter& filter_config);
     230             : 
     231             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     232             :                 const StreamInfo::StreamInfo& info) const override;
     233             : 
     234             : private:
     235             :   LogTypeHashSet types_;
     236             :   bool exclude_;
     237             : };
     238             : 
     239             : /**
     240             :  * Filters requests based on dynamic metadata
     241             :  */
     242             : class MetadataFilter : public Filter {
     243             : public:
     244             :   MetadataFilter(const envoy::config::accesslog::v3::MetadataFilter& filter_config);
     245             : 
     246             :   bool evaluate(const Formatter::HttpFormatterContext& context,
     247             :                 const StreamInfo::StreamInfo& info) const override;
     248             : 
     249             : private:
     250             :   Matchers::ValueMatcherConstSharedPtr present_matcher_;
     251             :   Matchers::ValueMatcherConstSharedPtr value_matcher_;
     252             : 
     253             :   std::vector<std::string> path_;
     254             : 
     255             :   const bool default_match_;
     256             :   const std::string filter_;
     257             : };
     258             : 
     259             : /**
     260             :  * Access log factory that reads the configuration from proto.
     261             :  */
     262             : class AccessLogFactory {
     263             : public:
     264             :   /**
     265             :    * Read a filter definition from proto and instantiate an Instance. This method is used
     266             :    * to create access log instances that need access to listener properties.
     267             :    */
     268             :   static InstanceSharedPtr fromProto(const envoy::config::accesslog::v3::AccessLog& config,
     269             :                                      Server::Configuration::FactoryContext& context);
     270             : 
     271             :   /**
     272             :    * Template method to create an access log filter from proto configuration for non-HTTP access
     273             :    * loggers.
     274             :    */
     275             :   template <class Context>
     276             :   static FilterBasePtr<Context>
     277             :   accessLogFilterFromProto(const envoy::config::accesslog::v3::AccessLogFilter& config,
     278             :                            Server::Configuration::FactoryContext& context) {
     279             :     if (!config.has_extension_filter()) {
     280             :       ExceptionUtil::throwEnvoyException(
     281             :           "Access log filter: only extension filter is supported by non-HTTP access loggers.");
     282             :     }
     283             : 
     284             :     auto& factory = Config::Utility::getAndCheckFactory<ExtensionFilterFactoryBase<Context>>(
     285             :         config.extension_filter());
     286             :     return factory.createFilter(config.extension_filter(), context);
     287             :   }
     288             : 
     289             :   /**
     290             :    * Template method to create an access logger instance from proto configuration for non-HTTP
     291             :    * access loggers.
     292             :    */
     293             :   template <class Context>
     294             :   static InstanceBaseSharedPtr<Context>
     295             :   accessLoggerFromProto(const envoy::config::accesslog::v3::AccessLog& config,
     296             :                         Server::Configuration::FactoryContext& context) {
     297             :     FilterBasePtr<Context> filter;
     298             :     if (config.has_filter()) {
     299             :       filter = accessLogFilterFromProto<Context>(config.filter(), context);
     300             :     }
     301             : 
     302             :     auto& factory =
     303             :         Config::Utility::getAndCheckFactory<AccessLogInstanceFactoryBase<Context>>(config);
     304             :     ProtobufTypes::MessagePtr message = Config::Utility::translateToFactoryConfig(
     305             :         config, context.messageValidationVisitor(), factory);
     306             : 
     307             :     return factory.createAccessLogInstance(*message, std::move(filter), context);
     308             :   }
     309             : };
     310             : 
     311             : } // namespace AccessLog
     312             : } // namespace Envoy

Generated by: LCOV version 1.15