Skip to content

Commit

Permalink
access log formatter: use new formatter context rather than multiple …
Browse files Browse the repository at this point in the history
…parameters (1/3) (envoyproxy#30734)

access log formatter: use new formatter context rather than multiple parameters (1/3)
Additional Description:

Part of templated formatter and access log support. HttpFormatterContext is used by the formatter to extract information of HTTP stream, like headers, trailers, etc. And now, this patchs will update the API of logger to take HttpFormatterContext rather than multiple independent parameters.

NOTE 1: to ensure these changes could get reasonable review, I split it to three sub-patches. This is the first one and only update the emitLog().
NOTE 2: this PR won't change any logic or behavior be may effect building of third party folks. Sorry for that. :(

NOTE3: this PR moved HttpFormatterContext to separated header file to avoid cycle dependency.
NOTE4: this PR moved AccessLogInstanceFactory from envoy/server/access_log_config.h to envoy/access_log/access_log_config.h. Because this factory should be replaced by template finally and moved it in this patch could avoid further updates to loggers in following PRs.

Risk Level: low. No logic update.
Testing: n/a.
Docs Changes: n/a.
Release Notes: n/a.
Platform Specific Features: n/a.

Signed-off-by: wbpcode <wbphub@live.com>
  • Loading branch information
code authored Nov 7, 2023
1 parent a9d8eb3 commit cefd660
Show file tree
Hide file tree
Showing 49 changed files with 302 additions and 432 deletions.
1 change: 1 addition & 0 deletions envoy/access_log/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ envoy_cc_library(
deps = [
"//envoy/config:typed_config_interface",
"//envoy/filesystem:filesystem_interface",
"//envoy/formatter:http_formatter_context_interface",
"//envoy/http:header_map_interface",
"//envoy/stream_info:stream_info_interface",
"//source/common/protobuf",
Expand Down
1 change: 1 addition & 0 deletions envoy/access_log/access_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "envoy/common/pure.h"
#include "envoy/data/accesslog/v3/accesslog.pb.h"
#include "envoy/filesystem/filesystem.h"
#include "envoy/formatter/http_formatter_context.h"
#include "envoy/http/header_map.h"
#include "envoy/stream_info/stream_info.h"

Expand Down
37 changes: 37 additions & 0 deletions envoy/access_log/access_log_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,42 @@ template <class Context> class AccessLogInstanceFactoryBase : public Config::Typ
const std::string category_;
};

/**
* Implemented for each AccessLog::Instance and registered via Registry::registerFactory or the
* convenience class RegisterFactory.
*/
class AccessLogInstanceFactory : public Config::TypedFactory {
public:
~AccessLogInstanceFactory() override = default;

/**
* Create a particular AccessLog::Instance implementation from a config proto. If the
* implementation is unable to produce a factory with the provided parameters, it should throw an
* EnvoyException. The returned pointer should never be nullptr.
* @param config the custom configuration for this access log type.
* @param filter filter to determine whether a particular request should be logged. If no filter
* was specified in the configuration, argument will be nullptr.
* @param context access log context through which persistent resources can be accessed.
*/
virtual AccessLog::InstanceSharedPtr
createAccessLogInstance(const Protobuf::Message& config, AccessLog::FilterPtr&& filter,
Server::Configuration::ListenerAccessLogFactoryContext& context) PURE;

/**
* Create a particular AccessLog::Instance implementation from a config proto. If the
* implementation is unable to produce a factory with the provided parameters, it should throw an
* EnvoyException. The returned pointer should never be nullptr.
* @param config the custom configuration for this access log type.
* @param filter filter to determine whether a particular request should be logged. If no filter
* was specified in the configuration, argument will be nullptr.
* @param context general filter context through which persistent resources can be accessed.
*/
virtual AccessLog::InstanceSharedPtr
createAccessLogInstance(const Protobuf::Message& config, AccessLog::FilterPtr&& filter,
Server::Configuration::CommonFactoryContext& context) PURE;

std::string category() const override { return "envoy.access_loggers"; }
};

} // namespace AccessLog
} // namespace Envoy
13 changes: 12 additions & 1 deletion envoy/formatter/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ licenses(["notice"]) # Apache 2

envoy_package()

envoy_cc_library(
name = "http_formatter_context_interface",
hdrs = [
"http_formatter_context.h",
],
deps = [
"//envoy/http:header_map_interface",
"@envoy_api//envoy/data/accesslog/v3:pkg_cc_proto",
],
)

envoy_cc_library(
name = "substitution_formatter_interface",
hdrs = [
"substitution_formatter.h",
"substitution_formatter_base.h",
],
deps = [
"//envoy/access_log:access_log_interface",
":http_formatter_context_interface",
"//envoy/config:typed_config_interface",
"//envoy/http:header_map_interface",
"//envoy/server:factory_context_interface",
Expand Down
115 changes: 115 additions & 0 deletions envoy/formatter/http_formatter_context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#pragma once

#include "envoy/data/accesslog/v3/accesslog.pb.h"
#include "envoy/http/header_map.h"

namespace Envoy {
namespace Formatter {

using AccessLogType = envoy::data::accesslog::v3::AccessLogType;

/**
* HTTP specific substitution formatter context for HTTP access logs or formatters.
* TODO(wbpcode): maybe we should move this class to envoy/http folder and rename it
* for more general usage.
*/
class HttpFormatterContext {
public:
/**
* Constructor that uses the provided request/response headers, response trailers, local reply
* body, and access log type. Any of the parameters can be nullptr/empty.
*
* @param request_headers supplies the request headers.
* @param response_headers supplies the response headers.
* @param response_trailers supplies the response trailers.
* @param local_reply_body supplies the local reply body.
* @param log_type supplies the access log type.
*/
HttpFormatterContext(const Http::RequestHeaderMap* request_headers = nullptr,
const Http::ResponseHeaderMap* response_headers = nullptr,
const Http::ResponseTrailerMap* response_trailers = nullptr,
absl::string_view local_reply_body = {},
AccessLogType log_type = AccessLogType::NotSet);
/**
* Set or overwrite the request headers.
* @param request_headers supplies the request headers.
*/
HttpFormatterContext& setRequestHeaders(const Http::RequestHeaderMap& request_headers) {
request_headers_ = &request_headers;
return *this;
}
/**
* Set or overwrite the response headers.
* @param response_headers supplies the response headers.
*/
HttpFormatterContext& setResponseHeaders(const Http::ResponseHeaderMap& response_headers) {
response_headers_ = &response_headers;
return *this;
}

/**
* Set or overwrite the response trailers.
* @param response_trailers supplies the response trailers.
*/
HttpFormatterContext& setResponseTrailers(const Http::ResponseTrailerMap& response_trailers) {
response_trailers_ = &response_trailers;
return *this;
}

/**
* Set or overwrite the local reply body.
* @param local_reply_body supplies the local reply body.
*/
HttpFormatterContext& setLocalReplyBody(absl::string_view local_reply_body) {
local_reply_body_ = local_reply_body;
return *this;
}

/**
* Set or overwrite the access log type.
* @param log_type supplies the access log type.
*/
HttpFormatterContext& setAccessLogType(AccessLogType log_type) {
log_type_ = log_type;
return *this;
}

/**
* @return const Http::RequestHeaderMap& the request headers. Empty request header map if no
* request headers are available.
*/
const Http::RequestHeaderMap& requestHeaders() const;

/**
* @return const Http::ResponseHeaderMap& the response headers. Empty respnose header map if
* no response headers are available.
*/
const Http::ResponseHeaderMap& responseHeaders() const;

/**
* @return const Http::ResponseTrailerMap& the response trailers. Empty response trailer map
* if no response trailers are available.
*/
const Http::ResponseTrailerMap& responseTrailers() const;

/**
* @return absl::string_view the local reply body. Empty if no local reply body.
*/
absl::string_view localReplyBody() const;

/**
* @return AccessLog::AccessLogType the type of access log. NotSet if this is not used for
* access logging.
*/
AccessLogType accessLogType() const;

private:
const Http::RequestHeaderMap* request_headers_{};
const Http::ResponseHeaderMap* response_headers_{};
const Http::ResponseTrailerMap* response_trailers_{};
absl::string_view local_reply_body_{};
AccessLogType log_type_{AccessLogType::NotSet};
};

} // namespace Formatter
} // namespace Envoy
102 changes: 1 addition & 101 deletions envoy/formatter/substitution_formatter.h
Original file line number Diff line number Diff line change
@@ -1,112 +1,12 @@
#pragma once

#include "envoy/formatter/http_formatter_context.h"
#include "envoy/formatter/substitution_formatter_base.h"
#include "envoy/http/header_map.h"

namespace Envoy {
namespace Formatter {

/**
* HTTP specific substitution formatter context for HTTP access logs or formatters.
*/
class HttpFormatterContext {
public:
/**
* Constructor that uses the provided request/response headers, response trailers, local reply
* body, and access log type. Any of the parameters can be nullptr/empty.
*
* @param request_headers supplies the request headers.
* @param response_headers supplies the response headers.
* @param response_trailers supplies the response trailers.
* @param local_reply_body supplies the local reply body.
* @param log_type supplies the access log type.
*/
HttpFormatterContext(const Http::RequestHeaderMap* request_headers = nullptr,
const Http::ResponseHeaderMap* response_headers = nullptr,
const Http::ResponseTrailerMap* response_trailers = nullptr,
absl::string_view local_reply_body = {},
AccessLog::AccessLogType log_type = AccessLog::AccessLogType::NotSet);
/**
* Set or overwrite the request headers.
* @param request_headers supplies the request headers.
*/
HttpFormatterContext& setRequestHeaders(const Http::RequestHeaderMap& request_headers) {
request_headers_ = &request_headers;
return *this;
}
/**
* Set or overwrite the response headers.
* @param response_headers supplies the response headers.
*/
HttpFormatterContext& setResponseHeaders(const Http::ResponseHeaderMap& response_headers) {
response_headers_ = &response_headers;
return *this;
}

/**
* Set or overwrite the response trailers.
* @param response_trailers supplies the response trailers.
*/
HttpFormatterContext& setResponseTrailers(const Http::ResponseTrailerMap& response_trailers) {
response_trailers_ = &response_trailers;
return *this;
}

/**
* Set or overwrite the local reply body.
* @param local_reply_body supplies the local reply body.
*/
HttpFormatterContext& setLocalReplyBody(absl::string_view local_reply_body) {
local_reply_body_ = local_reply_body;
return *this;
}

/**
* Set or overwrite the access log type.
* @param log_type supplies the access log type.
*/
HttpFormatterContext& setAccessLogType(AccessLog::AccessLogType log_type) {
log_type_ = log_type;
return *this;
}

/**
* @return const Http::RequestHeaderMap& the request headers. Empty request header map if no
* request headers are available.
*/
const Http::RequestHeaderMap& requestHeaders() const;

/**
* @return const Http::ResponseHeaderMap& the response headers. Empty respnose header map if
* no response headers are available.
*/
const Http::ResponseHeaderMap& responseHeaders() const;

/**
* @return const Http::ResponseTrailerMap& the response trailers. Empty response trailer map
* if no response trailers are available.
*/
const Http::ResponseTrailerMap& responseTrailers() const;

/**
* @return absl::string_view the local reply body. Empty if no local reply body.
*/
absl::string_view localReplyBody() const;

/**
* @return AccessLog::AccessLogType the type of access log. NotSet if this is not used for
* access logging.
*/
AccessLog::AccessLogType accessLogType() const;

private:
const Http::RequestHeaderMap* request_headers_{};
const Http::ResponseHeaderMap* response_headers_{};
const Http::ResponseTrailerMap* response_trailers_{};
absl::string_view local_reply_body_{};
AccessLog::AccessLogType log_type_{AccessLog::AccessLogType::NotSet};
};

using Formatter = FormatterBase<HttpFormatterContext>;
using FormatterPtr = std::unique_ptr<Formatter>;
using FormatterConstSharedPtr = std::shared_ptr<const Formatter>;
Expand Down
10 changes: 0 additions & 10 deletions envoy/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,6 @@ licenses(["notice"]) # Apache 2

envoy_package()

envoy_cc_library(
name = "access_log_config_interface",
hdrs = ["access_log_config.h"],
deps = [
":filter_config_interface",
"//envoy/access_log:access_log_interface",
"//source/common/protobuf",
],
)

envoy_cc_library(
name = "admin_interface",
hdrs = ["admin.h"],
Expand Down
54 changes: 0 additions & 54 deletions envoy/server/access_log_config.h

This file was deleted.

1 change: 0 additions & 1 deletion source/common/access_log/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ envoy_cc_library(
"//envoy/filesystem:filesystem_interface",
"//envoy/http:header_map_interface",
"//envoy/runtime:runtime_interface",
"//envoy/server:access_log_config_interface",
"//envoy/upstream:upstream_interface",
"//source/common/common:assert_lib",
"//source/common/common:utility_lib",
Expand Down
Loading

0 comments on commit cefd660

Please sign in to comment.