This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 83ec495a12 Remove virtual dispatch from LogData (#13123)
83ec495a12 is described below
commit 83ec495a12b5e8a8795c2feb43289532b5531de7
Author: Brian Neradt <[email protected]>
AuthorDate: Wed Apr 29 14:28:23 2026 -0500
Remove virtual dispatch from LogData (#13123)
This addresses a performance regression added by #13059.
Malformed pre-transaction logging introduced an extra virtual data
interface on the normal access log path. That made every completed
transaction pay for indirection that is only needed for rare
protocol-layer failures.
This replaces the virtual hierarchy with a concrete composed
TransactionLogData wrapper. This keeps LogAccess using one data object
while routing the common HttpSM path through direct getters and falling
back to owned pre-transaction data only when no HttpSM exists.
---
include/proxy/PreTransactionLogData.h | 151 +--
include/proxy/http/CompletedTransactionLogData.h | 208 ----
include/proxy/logging/Log.h | 2 +-
include/proxy/logging/LogAccess.h | 4 +-
include/proxy/logging/TransactionLogData.h | 632 +++---------
src/proxy/ProxyTransaction.cc | 4 +-
src/proxy/http/CMakeLists.txt | 1 -
src/proxy/http/CompletedTransactionLogData.cc | 837 ----------------
src/proxy/http/HttpBodyFactory.cc | 6 +-
src/proxy/http/HttpSM.cc | 10 +-
src/proxy/logging/CMakeLists.txt | 12 +-
src/proxy/logging/TransactionLogData.cc | 1117 ++++++++++++++++++++++
src/proxy/logging/unit-tests/test_LogAccess.cc | 10 +-
13 files changed, 1284 insertions(+), 1710 deletions(-)
diff --git a/include/proxy/PreTransactionLogData.h
b/include/proxy/PreTransactionLogData.h
index 9d65e66761..0ec03c646b 100644
--- a/include/proxy/PreTransactionLogData.h
+++ b/include/proxy/PreTransactionLogData.h
@@ -24,7 +24,9 @@
#pragma once
-#include "proxy/logging/TransactionLogData.h"
+#include "proxy/Milestones.h"
+#include "proxy/hdrs/HTTP.h"
+#include "tscore/ink_inet.h"
#include <string>
@@ -36,160 +38,21 @@
* copied request and session metadata needed to emit a best-effort
* transaction log entry for those failures.
*
- * Unlike TransactionLogData (which reads from a live HttpSM), this class
- * owns its milestones, addresses, and strings because the originating
- * stream is about to be destroyed.
+ * This class owns its milestones, addresses, and strings because the
+ * originating stream is about to be destroyed.
*/
-class PreTransactionLogData : public TransactionLogData
+class PreTransactionLogData
{
public:
PreTransactionLogData() = default;
- ~PreTransactionLogData() override
+ ~PreTransactionLogData()
{
if (owned_client_request.valid()) {
owned_client_request.destroy();
}
}
- // ===== Milestones =====
-
- TransactionMilestones const *
- get_milestones() const override
- {
- return &owned_milestones;
- }
-
- // ===== Headers =====
-
- HTTPHdr *
- get_client_request() const override
- {
- if (owned_client_request.valid()) {
- return const_cast<HTTPHdr *>(&owned_client_request);
- }
- return nullptr;
- }
-
- // ===== Client request URL / path =====
-
- const char *
- get_client_req_url_str() const override
- {
- return owned_url.empty() ? nullptr : owned_url.c_str();
- }
- int
- get_client_req_url_len() const override
- {
- return static_cast<int>(owned_url.size());
- }
- const char *
- get_client_req_url_path_str() const override
- {
- return owned_path.empty() ? nullptr : owned_path.c_str();
- }
- int
- get_client_req_url_path_len() const override
- {
- return static_cast<int>(owned_path.size());
- }
-
- // ===== Client addressing =====
-
- sockaddr const *
- get_client_addr() const override
- {
- return &owned_client_addr.sa;
- }
- sockaddr const *
- get_client_src_addr() const override
- {
- return &owned_client_src_addr.sa;
- }
- sockaddr const *
- get_client_dst_addr() const override
- {
- return &owned_client_dst_addr.sa;
- }
- uint16_t
- get_client_port() const override
- {
- return m_client_port;
- }
-
- // ===== Squid codes =====
-
- SquidLogCode
- get_log_code() const override
- {
- return m_log_code;
- }
- SquidHitMissCode
- get_hit_miss_code() const override
- {
- return m_hit_miss_code;
- }
- SquidHierarchyCode
- get_hier_code() const override
- {
- return m_hier_code;
- }
-
- // ===== Transaction identifiers =====
-
- int64_t
- get_connection_id() const override
- {
- return m_connection_id;
- }
- int
- get_transaction_id() const override
- {
- return m_transaction_id;
- }
-
- // ===== Protocol info =====
-
- const char *
- get_client_protocol() const override
- {
- return owned_client_protocol_str.empty() ? nullptr :
owned_client_protocol_str.c_str();
- }
-
- // ===== Connection flags =====
-
- bool
- get_client_connection_is_ssl() const override
- {
- return m_client_connection_is_ssl;
- }
-
- // ===== Server transaction count =====
-
- int64_t
- get_server_transact_count() const override
- {
- return m_server_transact_count;
- }
-
- // ===== Fallback fields for pre-transaction logging =====
-
- std::string_view
- get_method() const override
- {
- return owned_method;
- }
- std::string_view
- get_scheme() const override
- {
- return owned_scheme;
- }
- std::string_view
- get_client_protocol_str() const override
- {
- return owned_client_protocol_str;
- }
-
// ===== Owned backing storage (public for ProxyTransaction to populate).
=====
HTTPHdr owned_client_request;
diff --git a/include/proxy/http/CompletedTransactionLogData.h
b/include/proxy/http/CompletedTransactionLogData.h
deleted file mode 100644
index e8593d4220..0000000000
--- a/include/proxy/http/CompletedTransactionLogData.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/** @file
-
- CompletedTransactionLogData populates TransactionLogData from a live HttpSM.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you 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.
- */
-
-#pragma once
-
-#include "proxy/logging/TransactionLogData.h"
-
-class HttpSM;
-
-/** Provide TransactionLogData from a live HttpSM via virtual getters.
- *
- * Each getter reads directly from m_http_sm on demand, avoiding the need to
- * copy all fields upfront. The HttpSM must outlive this object.
- */
-class CompletedTransactionLogData : public TransactionLogData
-{
-public:
- /** Construct from a live HttpSM.
- *
- * @param[in] sm The HttpSM for the completing transaction.
- */
- explicit CompletedTransactionLogData(HttpSM *sm);
-
- void *http_sm_for_plugins() const override;
-
- // ===== Milestones =====
- TransactionMilestones const *get_milestones() const override;
-
- // ===== Headers =====
- HTTPHdr *get_client_request() const override;
- HTTPHdr *get_proxy_response() const override;
- HTTPHdr *get_proxy_request() const override;
- HTTPHdr *get_server_response() const override;
- HTTPHdr *get_cache_response() const override;
-
- // ===== Client request URL / path =====
- const char *get_client_req_url_str() const override;
- int get_client_req_url_len() const override;
- const char *get_client_req_url_path_str() const override;
- int get_client_req_url_path_len() const override;
-
- // ===== Proxy response content-type / reason =====
- char *get_proxy_resp_content_type_str() const override;
- int get_proxy_resp_content_type_len() const override;
- char *get_proxy_resp_reason_phrase_str() const override;
- int get_proxy_resp_reason_phrase_len() const override;
-
- // ===== Unmapped URL =====
- char *get_unmapped_url_str() const override;
- int get_unmapped_url_len() const override;
-
- // ===== Cache lookup URL =====
- char *get_cache_lookup_url_str() const override;
- int get_cache_lookup_url_len() const override;
-
- // ===== Client addressing =====
- sockaddr const *get_client_addr() const override;
- sockaddr const *get_client_src_addr() const override;
- sockaddr const *get_client_dst_addr() const override;
- sockaddr const *get_verified_client_addr() const override;
- uint16_t get_client_port() const override;
-
- // ===== Server addressing =====
- sockaddr const *get_server_src_addr() const override;
- sockaddr const *get_server_dst_addr() const override;
- sockaddr const *get_server_info_dst_addr() const override;
- const char *get_server_name() const override;
-
- // ===== Squid codes =====
- SquidLogCode get_log_code() const override;
- SquidSubcode get_subcode() const override;
- SquidHitMissCode get_hit_miss_code() const override;
- SquidHierarchyCode get_hier_code() const override;
-
- // ===== Byte counters =====
- int64_t get_client_request_body_bytes() const override;
- int64_t get_client_response_hdr_bytes() const override;
- int64_t get_client_response_body_bytes() const override;
- int64_t get_server_request_body_bytes() const override;
- int64_t get_server_response_body_bytes() const override;
- int64_t get_cache_response_body_bytes() const override;
- int64_t get_cache_response_hdr_bytes() const override;
-
- // ===== Transaction identifiers =====
- int64_t get_sm_id() const override;
- int64_t get_connection_id() const override;
- int get_transaction_id() const override;
- int get_transaction_priority_weight() const override;
- int get_transaction_priority_dependence() const override;
-
- // ===== Plugin info =====
- int64_t get_plugin_id() const override;
- const char *get_plugin_tag() const override;
-
- // ===== Protocol info =====
- const char *get_client_protocol() const override;
- const char *get_server_protocol() const override;
- const char *get_client_sec_protocol() const override;
- const char *get_client_cipher_suite() const override;
- const char *get_client_curve() const override;
- const char *get_client_security_group() const override;
- int get_client_alpn_id() const override;
-
- // ===== SNI =====
- const char *get_sni_server_name() const override;
-
- // ===== Connection flags =====
- bool get_client_tcp_reused() const override;
- bool get_client_connection_is_ssl() const override;
- bool get_client_ssl_reused() const override;
- bool get_is_internal() const override;
- bool get_server_connection_is_ssl() const override;
- bool get_server_ssl_reused() const override;
- int get_server_connection_provided_cert() const override;
- int get_client_provided_cert() const override;
-
- // ===== Server transaction count =====
- int64_t get_server_transact_count() const override;
-
- // ===== Finish status =====
- int get_client_finish_status_code() const override;
- int get_proxy_finish_status_code() const override;
-
- // ===== Error codes =====
- const char *get_client_rx_error_code() const override;
- const char *get_client_tx_error_code() const override;
-
- // ===== MPTCP =====
- std::optional<bool> get_mptcp_state() const override;
-
- // ===== Misc transaction state =====
- in_port_t get_incoming_port() const override;
- int get_orig_scheme() const override;
- int64_t get_congestion_control_crat() const override;
-
- // ===== Cache state =====
- int get_cache_write_code() const override;
- int get_cache_transform_write_code() const override;
- int get_cache_open_read_tries() const override;
- int get_cache_open_write_tries() const override;
- int get_max_cache_open_write_retries() const override;
-
- // ===== Retry attempts =====
- int64_t get_simple_retry_attempts() const override;
- int64_t get_unavailable_retry_attempts() const override;
- int64_t get_retry_attempts_saved() const override;
-
- // ===== Status plugin entry name =====
- std::string_view get_http_return_code_setter_name() const override;
-
- // ===== Proxy Protocol =====
- int get_pp_version() const override;
- sockaddr const *get_pp_src_addr() const override;
- sockaddr const *get_pp_dst_addr() const override;
- std::string_view get_pp_authority() const override;
- std::string_view get_pp_tls_cipher() const override;
- std::string_view get_pp_tls_version() const override;
- std::string_view get_pp_tls_group() const override;
-
- // ===== Server response Transfer-Encoding =====
- std::string_view get_server_response_transfer_encoding() const override;
-
-private:
- HttpSM *m_http_sm;
-
- // Cached values for fields that require computation or string formatting.
- mutable char m_client_rx_error_code[10] = {'-', '\0'};
- mutable char m_client_tx_error_code[10] = {'-', '\0'};
- mutable bool m_error_codes_formatted = false;
-
- // Cached URL string pointers (computed on first access).
- mutable const char *m_client_req_url_str = nullptr;
- mutable int m_client_req_url_len = 0;
- mutable const char *m_client_req_url_path_str = nullptr;
- mutable int m_client_req_url_path_len = 0;
- mutable bool m_url_cached = false;
-
- // Cached content-type pointers (computed on first access).
- mutable char *m_proxy_resp_content_type_str = nullptr;
- mutable int m_proxy_resp_content_type_len = 0;
- mutable char *m_proxy_resp_reason_phrase_str = nullptr;
- mutable int m_proxy_resp_reason_phrase_len = 0;
- mutable bool m_content_type_cached = false;
-
- void cache_url_strings() const;
- void cache_content_type() const;
- void format_error_codes() const;
-};
diff --git a/include/proxy/logging/Log.h b/include/proxy/logging/Log.h
index 1a7c81114f..20019bf6ce 100644
--- a/include/proxy/logging/Log.h
+++ b/include/proxy/logging/Log.h
@@ -43,7 +43,7 @@
@section example Example usage of the API
@code
- // Populate a LogData (e.g. TransactionLogData or PreTransactionLogData),
then:
+ // Populate a TransactionLogData, then:
LogAccess entry(data);
int ret = Log::access(&entry);
@endcode
diff --git a/include/proxy/logging/LogAccess.h
b/include/proxy/logging/LogAccess.h
index 7701944df5..e449b674b2 100644
--- a/include/proxy/logging/LogAccess.h
+++ b/include/proxy/logging/LogAccess.h
@@ -123,8 +123,8 @@ public:
* The caller retains ownership of @a data, which must outlive the
* synchronous Log::access() call that marshals this entry.
*
- * @param[in] data Populated TransactionLogData (CompletedTransactionLogData
- * or PreTransactionLogData).
+ * @param[in] data Populated TransactionLogData for a completed or
+ * pre-transaction entry.
*/
explicit LogAccess(TransactionLogData &data);
diff --git a/include/proxy/logging/TransactionLogData.h
b/include/proxy/logging/TransactionLogData.h
index 99248614dd..0c1eefd53a 100644
--- a/include/proxy/logging/TransactionLogData.h
+++ b/include/proxy/logging/TransactionLogData.h
@@ -1,6 +1,6 @@
/** @file
- Base class providing the data interface for access log entries.
+ Concrete data accessor for access log entries.
@section license License
@@ -30,569 +30,193 @@
#include <optional>
#include <string_view>
-class HTTPHdr;
+class HttpSM;
+class PreTransactionLogData;
-/** Abstract base for the data backing a single access log entry.
+/** Provide access-log data from either a completed HttpSM or pre-transaction
storage.
*
- * Subclasses provide data from the appropriate source via virtual getters:
- * - CompletedTransactionLogData reads from HttpSM (defined in the http
- * module) for transactions that completed normally.
- * - PreTransactionLogData returns owned storage (defined in the proxy
- * module), for requests that never create an HttpSM.
- *
- * LogAccess reads only from this interface, so the logging module has no
- * compile-time dependency on the http module.
+ * The common completed-transaction path reads directly from @c HttpSM. The
+ * rare pre-transaction path reads from @c PreTransactionLogData, which owns
+ * copied request/session state for malformed requests rejected before HttpSM
+ * creation.
*/
class TransactionLogData
{
public:
- virtual ~TransactionLogData() = default;
-
- /** Return the HttpSM pointer for plugin custom marshal functions.
- *
- * Only TransactionLogData provides a non-null value. Pre-transaction
- * entries have no HttpSM, so plugins receive nullptr.
- *
- * @return An opaque pointer to the HttpSM, or nullptr.
- */
- virtual void *
- http_sm_for_plugins() const
- {
- return nullptr;
- }
+ explicit TransactionLogData(HttpSM *sm);
+ explicit TransactionLogData(PreTransactionLogData const &pre_data);
- // ===== Milestones =====
+ void *http_sm_for_plugins() const;
- virtual TransactionMilestones const *
- get_milestones() const
- {
- return nullptr;
- }
+ // ===== Milestones =====
+ TransactionMilestones const *get_milestones() const;
// ===== Headers =====
-
- virtual HTTPHdr *
- get_client_request() const
- {
- return nullptr;
- }
- virtual HTTPHdr *
- get_proxy_response() const
- {
- return nullptr;
- }
- virtual HTTPHdr *
- get_proxy_request() const
- {
- return nullptr;
- }
- virtual HTTPHdr *
- get_server_response() const
- {
- return nullptr;
- }
- virtual HTTPHdr *
- get_cache_response() const
- {
- return nullptr;
- }
+ HTTPHdr *get_client_request() const;
+ HTTPHdr *get_proxy_response() const;
+ HTTPHdr *get_proxy_request() const;
+ HTTPHdr *get_server_response() const;
+ HTTPHdr *get_cache_response() const;
// ===== Client request URL / path =====
-
- virtual const char *
- get_client_req_url_str() const
- {
- return nullptr;
- }
- virtual int
- get_client_req_url_len() const
- {
- return 0;
- }
- virtual const char *
- get_client_req_url_path_str() const
- {
- return nullptr;
- }
- virtual int
- get_client_req_url_path_len() const
- {
- return 0;
- }
+ const char *get_client_req_url_str() const;
+ int get_client_req_url_len() const;
+ const char *get_client_req_url_path_str() const;
+ int get_client_req_url_path_len() const;
// ===== Proxy response content-type / reason =====
-
- virtual char *
- get_proxy_resp_content_type_str() const
- {
- return nullptr;
- }
- virtual int
- get_proxy_resp_content_type_len() const
- {
- return 0;
- }
- virtual char *
- get_proxy_resp_reason_phrase_str() const
- {
- return nullptr;
- }
- virtual int
- get_proxy_resp_reason_phrase_len() const
- {
- return 0;
- }
+ char *get_proxy_resp_content_type_str() const;
+ int get_proxy_resp_content_type_len() const;
+ char *get_proxy_resp_reason_phrase_str() const;
+ int get_proxy_resp_reason_phrase_len() const;
// ===== Unmapped URL =====
-
- virtual char *
- get_unmapped_url_str() const
- {
- return nullptr;
- }
- virtual int
- get_unmapped_url_len() const
- {
- return 0;
- }
+ char *get_unmapped_url_str() const;
+ int get_unmapped_url_len() const;
// ===== Cache lookup URL =====
-
- virtual char *
- get_cache_lookup_url_str() const
- {
- return nullptr;
- }
- virtual int
- get_cache_lookup_url_len() const
- {
- return 0;
- }
+ char *get_cache_lookup_url_str() const;
+ int get_cache_lookup_url_len() const;
// ===== Client addressing =====
-
- virtual sockaddr const *
- get_client_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_client_src_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_client_dst_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_verified_client_addr() const
- {
- return nullptr;
- }
- virtual uint16_t
- get_client_port() const
- {
- return 0;
- }
+ sockaddr const *get_client_addr() const;
+ sockaddr const *get_client_src_addr() const;
+ sockaddr const *get_client_dst_addr() const;
+ sockaddr const *get_verified_client_addr() const;
+ uint16_t get_client_port() const;
// ===== Server addressing =====
-
- virtual sockaddr const *
- get_server_src_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_server_dst_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_server_info_dst_addr() const
- {
- return nullptr;
- }
- virtual const char *
- get_server_name() const
- {
- return nullptr;
- }
+ sockaddr const *get_server_src_addr() const;
+ sockaddr const *get_server_dst_addr() const;
+ sockaddr const *get_server_info_dst_addr() const;
+ const char *get_server_name() const;
// ===== Squid codes =====
-
- virtual SquidLogCode
- get_log_code() const
- {
- return SquidLogCode::EMPTY;
- }
- virtual SquidSubcode
- get_subcode() const
- {
- return SquidSubcode::EMPTY;
- }
- virtual SquidHitMissCode
- get_hit_miss_code() const
- {
- return SQUID_MISS_NONE;
- }
- virtual SquidHierarchyCode
- get_hier_code() const
- {
- return SquidHierarchyCode::NONE;
- }
+ SquidLogCode get_log_code() const;
+ SquidSubcode get_subcode() const;
+ SquidHitMissCode get_hit_miss_code() const;
+ SquidHierarchyCode get_hier_code() const;
// ===== Byte counters =====
-
- virtual int64_t
- get_client_request_body_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_client_response_hdr_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_client_response_body_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_server_request_body_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_server_response_body_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_cache_response_body_bytes() const
- {
- return 0;
- }
- virtual int64_t
- get_cache_response_hdr_bytes() const
- {
- return 0;
- }
+ int64_t get_client_request_body_bytes() const;
+ int64_t get_client_response_hdr_bytes() const;
+ int64_t get_client_response_body_bytes() const;
+ int64_t get_server_request_body_bytes() const;
+ int64_t get_server_response_body_bytes() const;
+ int64_t get_cache_response_body_bytes() const;
+ int64_t get_cache_response_hdr_bytes() const;
// ===== Transaction identifiers =====
-
- virtual int64_t
- get_sm_id() const
- {
- return 0;
- }
- virtual int64_t
- get_connection_id() const
- {
- return 0;
- }
- virtual int
- get_transaction_id() const
- {
- return 0;
- }
- virtual int
- get_transaction_priority_weight() const
- {
- return 0;
- }
- virtual int
- get_transaction_priority_dependence() const
- {
- return 0;
- }
+ int64_t get_sm_id() const;
+ int64_t get_connection_id() const;
+ int get_transaction_id() const;
+ int get_transaction_priority_weight() const;
+ int get_transaction_priority_dependence() const;
// ===== Plugin info =====
-
- virtual int64_t
- get_plugin_id() const
- {
- return 0;
- }
- virtual const char *
- get_plugin_tag() const
- {
- return nullptr;
- }
+ int64_t get_plugin_id() const;
+ const char *get_plugin_tag() const;
// ===== Protocol info =====
-
- virtual const char *
- get_client_protocol() const
- {
- return nullptr;
- }
- virtual const char *
- get_server_protocol() const
- {
- return nullptr;
- }
- virtual const char *
- get_client_sec_protocol() const
- {
- return nullptr;
- }
- virtual const char *
- get_client_cipher_suite() const
- {
- return nullptr;
- }
- virtual const char *
- get_client_curve() const
- {
- return nullptr;
- }
- virtual const char *
- get_client_security_group() const
- {
- return nullptr;
- }
- virtual int
- get_client_alpn_id() const
- {
- return -1;
- }
+ const char *get_client_protocol() const;
+ const char *get_server_protocol() const;
+ const char *get_client_sec_protocol() const;
+ const char *get_client_cipher_suite() const;
+ const char *get_client_curve() const;
+ const char *get_client_security_group() const;
+ int get_client_alpn_id() const;
// ===== SNI =====
-
- virtual const char *
- get_sni_server_name() const
- {
- return nullptr;
- }
+ const char *get_sni_server_name() const;
// ===== Connection flags =====
-
- virtual bool
- get_client_tcp_reused() const
- {
- return false;
- }
- virtual bool
- get_client_connection_is_ssl() const
- {
- return false;
- }
- virtual bool
- get_client_ssl_reused() const
- {
- return false;
- }
- virtual bool
- get_is_internal() const
- {
- return false;
- }
- virtual bool
- get_server_connection_is_ssl() const
- {
- return false;
- }
- virtual bool
- get_server_ssl_reused() const
- {
- return false;
- }
- virtual int
- get_server_connection_provided_cert() const
- {
- return 0;
- }
- virtual int
- get_client_provided_cert() const
- {
- return 0;
- }
+ bool get_client_tcp_reused() const;
+ bool get_client_connection_is_ssl() const;
+ bool get_client_ssl_reused() const;
+ bool get_is_internal() const;
+ bool get_server_connection_is_ssl() const;
+ bool get_server_ssl_reused() const;
+ int get_server_connection_provided_cert() const;
+ int get_client_provided_cert() const;
// ===== Server transaction count =====
-
- virtual int64_t
- get_server_transact_count() const
- {
- return 0;
- }
+ int64_t get_server_transact_count() const;
// ===== Finish status =====
-
- virtual int
- get_client_finish_status_code() const
- {
- return 0;
- }
- virtual int
- get_proxy_finish_status_code() const
- {
- return 0;
- }
+ int get_client_finish_status_code() const;
+ int get_proxy_finish_status_code() const;
// ===== Error codes =====
-
- virtual const char *
- get_client_rx_error_code() const
- {
- return "-";
- }
- virtual const char *
- get_client_tx_error_code() const
- {
- return "-";
- }
+ const char *get_client_rx_error_code() const;
+ const char *get_client_tx_error_code() const;
// ===== MPTCP =====
-
- virtual std::optional<bool>
- get_mptcp_state() const
- {
- return std::nullopt;
- }
+ std::optional<bool> get_mptcp_state() const;
// ===== Misc transaction state =====
-
- virtual in_port_t
- get_incoming_port() const
- {
- return 0;
- }
- virtual int
- get_orig_scheme() const
- {
- return -1;
- }
- virtual int64_t
- get_congestion_control_crat() const
- {
- return 0;
- }
+ in_port_t get_incoming_port() const;
+ int get_orig_scheme() const;
+ int64_t get_congestion_control_crat() const;
// ===== Cache state =====
-
- virtual int
- get_cache_write_code() const
- {
- return 0;
- }
- virtual int
- get_cache_transform_write_code() const
- {
- return 0;
- }
- virtual int
- get_cache_open_read_tries() const
- {
- return 0;
- }
- virtual int
- get_cache_open_write_tries() const
- {
- return 0;
- }
- virtual int
- get_max_cache_open_write_retries() const
- {
- return -1;
- }
+ int get_cache_write_code() const;
+ int get_cache_transform_write_code() const;
+ int get_cache_open_read_tries() const;
+ int get_cache_open_write_tries() const;
+ int get_max_cache_open_write_retries() const;
// ===== Retry attempts =====
-
- virtual int64_t
- get_simple_retry_attempts() const
- {
- return 0;
- }
- virtual int64_t
- get_unavailable_retry_attempts() const
- {
- return 0;
- }
- virtual int64_t
- get_retry_attempts_saved() const
- {
- return 0;
- }
+ int64_t get_simple_retry_attempts() const;
+ int64_t get_unavailable_retry_attempts() const;
+ int64_t get_retry_attempts_saved() const;
// ===== Status plugin entry name =====
-
- virtual std::string_view
- get_http_return_code_setter_name() const
- {
- return {};
- }
+ std::string_view get_http_return_code_setter_name() const;
// ===== Proxy Protocol =====
-
- virtual int
- get_pp_version() const
- {
- return 0;
- }
- virtual sockaddr const *
- get_pp_src_addr() const
- {
- return nullptr;
- }
- virtual sockaddr const *
- get_pp_dst_addr() const
- {
- return nullptr;
- }
- virtual std::string_view
- get_pp_authority() const
- {
- return {};
- }
- virtual std::string_view
- get_pp_tls_cipher() const
- {
- return {};
- }
- virtual std::string_view
- get_pp_tls_version() const
- {
- return {};
- }
- virtual std::string_view
- get_pp_tls_group() const
- {
- return {};
- }
+ int get_pp_version() const;
+ sockaddr const *get_pp_src_addr() const;
+ sockaddr const *get_pp_dst_addr() const;
+ std::string_view get_pp_authority() const;
+ std::string_view get_pp_tls_cipher() const;
+ std::string_view get_pp_tls_version() const;
+ std::string_view get_pp_tls_group() const;
// ===== Server response Transfer-Encoding =====
-
- virtual std::string_view
- get_server_response_transfer_encoding() const
- {
- return {};
- }
+ std::string_view get_server_response_transfer_encoding() const;
// ===== Fallback fields for pre-transaction logging =====
+ std::string_view get_method() const;
+ std::string_view get_scheme() const;
+ std::string_view get_client_protocol_str() const;
- virtual std::string_view
- get_method() const
- {
- return {};
- }
- virtual std::string_view
- get_scheme() const
- {
- return {};
- }
- virtual std::string_view
- get_client_protocol_str() const
- {
- return {};
- }
-
- // noncopyable
TransactionLogData(const TransactionLogData &) = delete;
TransactionLogData &operator=(const TransactionLogData &) = delete;
-protected:
- TransactionLogData() = default;
+private:
+ HttpSM *m_http_sm = nullptr;
+ PreTransactionLogData const *m_pre_data = nullptr;
+
+ // Cached values for fields that require computation or string formatting.
+ mutable char m_client_rx_error_code[10] = {'-', '\0'};
+ mutable char m_client_tx_error_code[10] = {'-', '\0'};
+ mutable bool m_error_codes_formatted = false;
+
+ // Cached URL string pointers (computed on first access).
+ mutable const char *m_client_req_url_str = nullptr;
+ mutable int m_client_req_url_len = 0;
+ mutable const char *m_client_req_url_path_str = nullptr;
+ mutable int m_client_req_url_path_len = 0;
+ mutable bool m_url_cached = false;
+
+ // Cached content-type pointers (computed on first access).
+ mutable char *m_proxy_resp_content_type_str = nullptr;
+ mutable int m_proxy_resp_content_type_len = 0;
+ mutable char *m_proxy_resp_reason_phrase_str = nullptr;
+ mutable int m_proxy_resp_reason_phrase_len = 0;
+ mutable bool m_content_type_cached = false;
+
+ void cache_url_strings() const;
+ void cache_content_type() const;
+ void format_error_codes() const;
};
diff --git a/src/proxy/ProxyTransaction.cc b/src/proxy/ProxyTransaction.cc
index ee02429722..c2a5a4584e 100644
--- a/src/proxy/ProxyTransaction.cc
+++ b/src/proxy/ProxyTransaction.cc
@@ -25,6 +25,7 @@
#include "proxy/Plugin.h"
#include "proxy/PreTransactionLogData.h"
#include "proxy/logging/LogAccess.h"
+#include "proxy/logging/TransactionLogData.h"
#include "proxy/logging/Log.h"
namespace
@@ -411,6 +412,7 @@ ProxyTransaction::log_pre_transaction_access(HTTPHdr const
*request, const char
data.owned_milestones[TS_MILESTONE_UA_READ_HEADER_DONE] = now;
data.owned_milestones[TS_MILESTONE_SM_FINISH] = now;
- LogAccess access(data);
+ TransactionLogData log_data(data);
+ LogAccess access(log_data);
Log::access(&access);
}
diff --git a/src/proxy/http/CMakeLists.txt b/src/proxy/http/CMakeLists.txt
index 94a3130803..55cf7ebd36 100644
--- a/src/proxy/http/CMakeLists.txt
+++ b/src/proxy/http/CMakeLists.txt
@@ -27,7 +27,6 @@ add_library(
HttpDebugNames.cc
HttpProxyServerMain.cc
HttpSM.cc
- CompletedTransactionLogData.cc
Http1ServerSession.cc
HttpSessionManager.cc
HttpTransact.cc
diff --git a/src/proxy/http/CompletedTransactionLogData.cc
b/src/proxy/http/CompletedTransactionLogData.cc
deleted file mode 100644
index 39d62a7517..0000000000
--- a/src/proxy/http/CompletedTransactionLogData.cc
+++ /dev/null
@@ -1,837 +0,0 @@
-/** @file
-
- CompletedTransactionLogData implementation: read TransactionLogData from a
- live HttpSM.
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you 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.
- */
-
-#include "proxy/http/CompletedTransactionLogData.h"
-#include "proxy/http/HttpSM.h"
-#include "proxy/logging/LogAccess.h"
-#include "proxy/hdrs/MIME.h"
-#include "../private/SSLProxySession.h"
-
-namespace
-{
-/** Map HttpTransact::CacheWriteStatus_t to LogCacheWriteCodeType. */
-int
-convert_cache_write_code(HttpTransact::CacheWriteStatus_t t)
-{
- switch (t) {
- case HttpTransact::CacheWriteStatus_t::NO_WRITE:
- return LOG_CACHE_WRITE_NONE;
- case HttpTransact::CacheWriteStatus_t::LOCK_MISS:
- return LOG_CACHE_WRITE_LOCK_MISSED;
- case HttpTransact::CacheWriteStatus_t::IN_PROGRESS:
- return LOG_CACHE_WRITE_LOCK_ABORTED;
- case HttpTransact::CacheWriteStatus_t::ERROR:
- return LOG_CACHE_WRITE_ERROR;
- case HttpTransact::CacheWriteStatus_t::COMPLETE:
- return LOG_CACHE_WRITE_COMPLETE;
- default:
- ink_assert(!"bad cache write code");
- return LOG_CACHE_WRITE_NONE;
- }
-}
-
-int
-compute_client_finish_status(HttpSM *sm)
-{
- HttpTransact::AbortState_t cl_abort_state = sm->t_state.client_info.abort;
- if (cl_abort_state == HttpTransact::ABORTED) {
- if (sm->t_state.client_info.state == HttpTransact::ACTIVE_TIMEOUT ||
- sm->t_state.client_info.state == HttpTransact::INACTIVE_TIMEOUT) {
- return LOG_FINISH_TIMEOUT;
- }
- return LOG_FINISH_INTR;
- }
- return LOG_FINISH_FIN;
-}
-
-int
-compute_proxy_finish_status(HttpSM *sm)
-{
- if (sm->t_state.current.server) {
- switch (sm->t_state.current.server->state) {
- case HttpTransact::ACTIVE_TIMEOUT:
- case HttpTransact::INACTIVE_TIMEOUT:
- return LOG_FINISH_TIMEOUT;
- case HttpTransact::CONNECTION_ERROR:
- return LOG_FINISH_INTR;
- default:
- if (sm->t_state.current.server->abort == HttpTransact::ABORTED) {
- return LOG_FINISH_INTR;
- }
- break;
- }
- }
- return LOG_FINISH_FIN;
-}
-} // end anonymous namespace
-
-CompletedTransactionLogData::CompletedTransactionLogData(HttpSM *sm) :
m_http_sm(sm)
-{
- ink_assert(sm != nullptr);
-}
-
-void *
-CompletedTransactionLogData::http_sm_for_plugins() const
-{
- return m_http_sm;
-}
-
-// ===== Milestones =====
-
-TransactionMilestones const *
-CompletedTransactionLogData::get_milestones() const
-{
- return &m_http_sm->milestones;
-}
-
-// ===== Headers =====
-
-HTTPHdr *
-CompletedTransactionLogData::get_client_request() const
-{
- HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
- if (hdr->client_request.valid()) {
- return &hdr->client_request;
- }
- return nullptr;
-}
-
-HTTPHdr *
-CompletedTransactionLogData::get_proxy_response() const
-{
- HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
- if (hdr->client_response.valid()) {
- return &hdr->client_response;
- }
- return nullptr;
-}
-
-HTTPHdr *
-CompletedTransactionLogData::get_proxy_request() const
-{
- HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
- if (hdr->server_request.valid()) {
- return &hdr->server_request;
- }
- return nullptr;
-}
-
-HTTPHdr *
-CompletedTransactionLogData::get_server_response() const
-{
- HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
- if (hdr->server_response.valid()) {
- return &hdr->server_response;
- }
- return nullptr;
-}
-
-HTTPHdr *
-CompletedTransactionLogData::get_cache_response() const
-{
- HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
- if (hdr->cache_response.valid()) {
- return &hdr->cache_response;
- }
- return nullptr;
-}
-
-// ===== Client request URL / path =====
-
-void
-CompletedTransactionLogData::cache_url_strings() const
-{
- if (m_url_cached) {
- return;
- }
- m_url_cached = true;
-
- HTTPHdr *client_request = get_client_request();
- if (client_request) {
- m_client_req_url_str =
client_request->url_string_get_ref(&m_client_req_url_len);
- auto path_sv = client_request->path_get();
- m_client_req_url_path_str = path_sv.data();
- m_client_req_url_path_len = static_cast<int>(path_sv.length());
- }
-}
-
-const char *
-CompletedTransactionLogData::get_client_req_url_str() const
-{
- cache_url_strings();
- return m_client_req_url_str;
-}
-
-int
-CompletedTransactionLogData::get_client_req_url_len() const
-{
- cache_url_strings();
- return m_client_req_url_len;
-}
-
-const char *
-CompletedTransactionLogData::get_client_req_url_path_str() const
-{
- cache_url_strings();
- return m_client_req_url_path_str;
-}
-
-int
-CompletedTransactionLogData::get_client_req_url_path_len() const
-{
- cache_url_strings();
- return m_client_req_url_path_len;
-}
-
-// ===== Proxy response content-type / reason =====
-
-void
-CompletedTransactionLogData::cache_content_type() const
-{
- if (m_content_type_cached) {
- return;
- }
- m_content_type_cached = true;
-
- HTTPHdr *proxy_response = get_proxy_response();
- if (proxy_response) {
- MIMEField *field =
proxy_response->field_find(static_cast<std::string_view>(MIME_FIELD_CONTENT_TYPE));
- if (field) {
- auto ct = field->value_get();
- m_proxy_resp_content_type_str = const_cast<char *>(ct.data());
- m_proxy_resp_content_type_len = ct.length();
- } else {
- constexpr std::string_view hidden_ct{"@Content-Type"};
- field = proxy_response->field_find(hidden_ct);
- if (field) {
- auto ct = field->value_get();
- m_proxy_resp_content_type_str = const_cast<char *>(ct.data());
- m_proxy_resp_content_type_len = ct.length();
- }
- }
- auto reason = proxy_response->reason_get();
- m_proxy_resp_reason_phrase_str = const_cast<char *>(reason.data());
- m_proxy_resp_reason_phrase_len = static_cast<int>(reason.length());
- }
-}
-
-char *
-CompletedTransactionLogData::get_proxy_resp_content_type_str() const
-{
- cache_content_type();
- return m_proxy_resp_content_type_str;
-}
-
-int
-CompletedTransactionLogData::get_proxy_resp_content_type_len() const
-{
- cache_content_type();
- return m_proxy_resp_content_type_len;
-}
-
-char *
-CompletedTransactionLogData::get_proxy_resp_reason_phrase_str() const
-{
- cache_content_type();
- return m_proxy_resp_reason_phrase_str;
-}
-
-int
-CompletedTransactionLogData::get_proxy_resp_reason_phrase_len() const
-{
- cache_content_type();
- return m_proxy_resp_reason_phrase_len;
-}
-
-// ===== Unmapped URL =====
-
-char *
-CompletedTransactionLogData::get_unmapped_url_str() const
-{
- if (m_http_sm->t_state.unmapped_url.valid()) {
- int len = 0;
- return m_http_sm->t_state.unmapped_url.string_get_ref(&len);
- }
- return nullptr;
-}
-
-int
-CompletedTransactionLogData::get_unmapped_url_len() const
-{
- if (m_http_sm->t_state.unmapped_url.valid()) {
- int len = 0;
- m_http_sm->t_state.unmapped_url.string_get_ref(&len);
- return len;
- }
- return 0;
-}
-
-// ===== Cache lookup URL =====
-
-char *
-CompletedTransactionLogData::get_cache_lookup_url_str() const
-{
- if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) {
- int len = 0;
- return
m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len);
- }
- return nullptr;
-}
-
-int
-CompletedTransactionLogData::get_cache_lookup_url_len() const
-{
- if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) {
- int len = 0;
- m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len);
- return len;
- }
- return 0;
-}
-
-// ===== Client addressing =====
-
-sockaddr const *
-CompletedTransactionLogData::get_client_addr() const
-{
- return &m_http_sm->t_state.effective_client_addr.sa;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_client_src_addr() const
-{
- return &m_http_sm->t_state.client_info.src_addr.sa;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_client_dst_addr() const
-{
- return &m_http_sm->t_state.client_info.dst_addr.sa;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_verified_client_addr() const
-{
- if (auto txn = m_http_sm->get_ua_txn(); txn) {
- sockaddr const *vaddr = txn->get_verified_client_addr();
- if (vaddr && ats_is_ip(vaddr)) {
- return vaddr;
- }
- }
- return nullptr;
-}
-
-uint16_t
-CompletedTransactionLogData::get_client_port() const
-{
- if (auto txn = m_http_sm->get_ua_txn(); txn) {
- return txn->get_client_port();
- }
- return 0;
-}
-
-// ===== Server addressing =====
-
-sockaddr const *
-CompletedTransactionLogData::get_server_src_addr() const
-{
- if (m_http_sm->t_state.current.server) {
- return &m_http_sm->t_state.current.server->src_addr.sa;
- }
- return nullptr;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_server_dst_addr() const
-{
- if (m_http_sm->t_state.current.server) {
- return &m_http_sm->t_state.current.server->dst_addr.sa;
- }
- return nullptr;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_server_info_dst_addr() const
-{
- return &m_http_sm->t_state.server_info.dst_addr.sa;
-}
-
-const char *
-CompletedTransactionLogData::get_server_name() const
-{
- if (m_http_sm->t_state.current.server) {
- return m_http_sm->t_state.current.server->name;
- }
- return nullptr;
-}
-
-// ===== Squid codes =====
-
-SquidLogCode
-CompletedTransactionLogData::get_log_code() const
-{
- return m_http_sm->t_state.squid_codes.log_code;
-}
-
-SquidSubcode
-CompletedTransactionLogData::get_subcode() const
-{
- return m_http_sm->t_state.squid_codes.subcode;
-}
-
-SquidHitMissCode
-CompletedTransactionLogData::get_hit_miss_code() const
-{
- return m_http_sm->t_state.squid_codes.hit_miss_code;
-}
-
-SquidHierarchyCode
-CompletedTransactionLogData::get_hier_code() const
-{
- return m_http_sm->t_state.squid_codes.hier_code;
-}
-
-// ===== Byte counters =====
-
-int64_t
-CompletedTransactionLogData::get_client_request_body_bytes() const
-{
- return m_http_sm->client_request_body_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_client_response_hdr_bytes() const
-{
- return m_http_sm->client_response_hdr_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_client_response_body_bytes() const
-{
- return m_http_sm->client_response_body_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_server_request_body_bytes() const
-{
- return m_http_sm->server_request_body_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_server_response_body_bytes() const
-{
- return m_http_sm->server_response_body_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_cache_response_body_bytes() const
-{
- return m_http_sm->cache_response_body_bytes;
-}
-
-int64_t
-CompletedTransactionLogData::get_cache_response_hdr_bytes() const
-{
- return m_http_sm->cache_response_hdr_bytes;
-}
-
-// ===== Transaction identifiers =====
-
-int64_t
-CompletedTransactionLogData::get_sm_id() const
-{
- return m_http_sm->sm_id;
-}
-
-int64_t
-CompletedTransactionLogData::get_connection_id() const
-{
- return m_http_sm->client_connection_id();
-}
-
-int
-CompletedTransactionLogData::get_transaction_id() const
-{
- return m_http_sm->client_transaction_id();
-}
-
-int
-CompletedTransactionLogData::get_transaction_priority_weight() const
-{
- return m_http_sm->client_transaction_priority_weight();
-}
-
-int
-CompletedTransactionLogData::get_transaction_priority_dependence() const
-{
- return m_http_sm->client_transaction_priority_dependence();
-}
-
-// ===== Plugin info =====
-
-int64_t
-CompletedTransactionLogData::get_plugin_id() const
-{
- return m_http_sm->plugin_id;
-}
-
-const char *
-CompletedTransactionLogData::get_plugin_tag() const
-{
- return m_http_sm->plugin_tag;
-}
-
-// ===== Protocol info =====
-
-const char *
-CompletedTransactionLogData::get_client_protocol() const
-{
- return m_http_sm->get_user_agent().get_client_protocol();
-}
-
-const char *
-CompletedTransactionLogData::get_server_protocol() const
-{
- return m_http_sm->server_protocol;
-}
-
-const char *
-CompletedTransactionLogData::get_client_sec_protocol() const
-{
- return m_http_sm->get_user_agent().get_client_sec_protocol();
-}
-
-const char *
-CompletedTransactionLogData::get_client_cipher_suite() const
-{
- return m_http_sm->get_user_agent().get_client_cipher_suite();
-}
-
-const char *
-CompletedTransactionLogData::get_client_curve() const
-{
- return m_http_sm->get_user_agent().get_client_curve();
-}
-
-const char *
-CompletedTransactionLogData::get_client_security_group() const
-{
- return m_http_sm->get_user_agent().get_client_security_group();
-}
-
-int
-CompletedTransactionLogData::get_client_alpn_id() const
-{
- return m_http_sm->get_user_agent().get_client_alpn_id();
-}
-
-// ===== SNI =====
-
-const char *
-CompletedTransactionLogData::get_sni_server_name() const
-{
- if (auto txn = m_http_sm->get_ua_txn(); txn) {
- if (auto ssn = txn->get_proxy_ssn(); ssn) {
- if (auto ssl = ssn->ssl(); ssl) {
- return ssl->client_sni_server_name();
- }
- }
- }
- return nullptr;
-}
-
-// ===== Connection flags =====
-
-bool
-CompletedTransactionLogData::get_client_tcp_reused() const
-{
- return m_http_sm->get_user_agent().get_client_tcp_reused();
-}
-
-bool
-CompletedTransactionLogData::get_client_connection_is_ssl() const
-{
- return m_http_sm->get_user_agent().get_client_connection_is_ssl();
-}
-
-bool
-CompletedTransactionLogData::get_client_ssl_reused() const
-{
- return m_http_sm->get_user_agent().get_client_ssl_reused();
-}
-
-bool
-CompletedTransactionLogData::get_is_internal() const
-{
- return m_http_sm->is_internal;
-}
-
-bool
-CompletedTransactionLogData::get_server_connection_is_ssl() const
-{
- return m_http_sm->server_connection_is_ssl;
-}
-
-bool
-CompletedTransactionLogData::get_server_ssl_reused() const
-{
- return m_http_sm->server_ssl_reused;
-}
-
-int
-CompletedTransactionLogData::get_server_connection_provided_cert() const
-{
- return m_http_sm->server_connection_provided_cert;
-}
-
-int
-CompletedTransactionLogData::get_client_provided_cert() const
-{
- if (auto txn = m_http_sm->get_ua_txn(); txn) {
- if (auto ssn = txn->get_proxy_ssn(); ssn) {
- if (auto ssl = ssn->ssl(); ssl) {
- return ssl->client_provided_certificate();
- }
- }
- }
- return 0;
-}
-
-// ===== Server transaction count =====
-
-int64_t
-CompletedTransactionLogData::get_server_transact_count() const
-{
- return m_http_sm->server_transact_count;
-}
-
-// ===== Finish status =====
-
-int
-CompletedTransactionLogData::get_client_finish_status_code() const
-{
- return compute_client_finish_status(m_http_sm);
-}
-
-int
-CompletedTransactionLogData::get_proxy_finish_status_code() const
-{
- return compute_proxy_finish_status(m_http_sm);
-}
-
-// ===== Error codes =====
-
-void
-CompletedTransactionLogData::format_error_codes() const
-{
- if (m_error_codes_formatted) {
- return;
- }
- m_error_codes_formatted = true;
- m_http_sm->t_state.client_info.rx_error_code.str(m_client_rx_error_code,
sizeof(m_client_rx_error_code));
- m_http_sm->t_state.client_info.tx_error_code.str(m_client_tx_error_code,
sizeof(m_client_tx_error_code));
-}
-
-const char *
-CompletedTransactionLogData::get_client_rx_error_code() const
-{
- format_error_codes();
- return m_client_rx_error_code;
-}
-
-const char *
-CompletedTransactionLogData::get_client_tx_error_code() const
-{
- format_error_codes();
- return m_client_tx_error_code;
-}
-
-// ===== MPTCP =====
-
-std::optional<bool>
-CompletedTransactionLogData::get_mptcp_state() const
-{
- return m_http_sm->mptcp_state;
-}
-
-// ===== Misc transaction state =====
-
-in_port_t
-CompletedTransactionLogData::get_incoming_port() const
-{
- return m_http_sm->t_state.request_data.incoming_port;
-}
-
-int
-CompletedTransactionLogData::get_orig_scheme() const
-{
- return m_http_sm->t_state.orig_scheme;
-}
-
-int64_t
-CompletedTransactionLogData::get_congestion_control_crat() const
-{
- return m_http_sm->t_state.congestion_control_crat;
-}
-
-// ===== Cache state =====
-
-int
-CompletedTransactionLogData::get_cache_write_code() const
-{
- return convert_cache_write_code(m_http_sm->t_state.cache_info.write_status);
-}
-
-int
-CompletedTransactionLogData::get_cache_transform_write_code() const
-{
- return
convert_cache_write_code(m_http_sm->t_state.cache_info.transform_write_status);
-}
-
-int
-CompletedTransactionLogData::get_cache_open_read_tries() const
-{
- return m_http_sm->get_cache_sm().get_open_read_tries();
-}
-
-int
-CompletedTransactionLogData::get_cache_open_write_tries() const
-{
- return m_http_sm->get_cache_sm().get_open_write_tries();
-}
-
-int
-CompletedTransactionLogData::get_max_cache_open_write_retries() const
-{
- return m_http_sm->t_state.txn_conf->max_cache_open_write_retries;
-}
-
-// ===== Retry attempts =====
-
-int64_t
-CompletedTransactionLogData::get_simple_retry_attempts() const
-{
- return m_http_sm->t_state.current.simple_retry_attempts;
-}
-
-int64_t
-CompletedTransactionLogData::get_unavailable_retry_attempts() const
-{
- return m_http_sm->t_state.current.unavailable_server_retry_attempts;
-}
-
-int64_t
-CompletedTransactionLogData::get_retry_attempts_saved() const
-{
- return m_http_sm->t_state.current.retry_attempts.saved();
-}
-
-// ===== Status plugin entry name =====
-
-std::string_view
-CompletedTransactionLogData::get_http_return_code_setter_name() const
-{
- return m_http_sm->t_state.http_return_code_setter_name;
-}
-
-// ===== Proxy Protocol =====
-
-int
-CompletedTransactionLogData::get_pp_version() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- return static_cast<int>(m_http_sm->t_state.pp_info.version);
- }
- return 0;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_pp_src_addr() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- return &m_http_sm->t_state.pp_info.src_addr.sa;
- }
- return nullptr;
-}
-
-sockaddr const *
-CompletedTransactionLogData::get_pp_dst_addr() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- return &m_http_sm->t_state.pp_info.dst_addr.sa;
- }
- return nullptr;
-}
-
-std::string_view
-CompletedTransactionLogData::get_pp_authority() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- if (auto authority_opt =
m_http_sm->t_state.pp_info.get_tlv(PP2_TYPE_AUTHORITY); authority_opt) {
- return *authority_opt;
- }
- }
- return {};
-}
-
-std::string_view
-CompletedTransactionLogData::get_pp_tls_cipher() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- if (auto cipher = m_http_sm->t_state.pp_info.get_tlv_ssl_cipher(); cipher)
{
- return *cipher;
- }
- }
- return {};
-}
-
-std::string_view
-CompletedTransactionLogData::get_pp_tls_version() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- if (auto version = m_http_sm->t_state.pp_info.get_tlv_ssl_version();
version) {
- return *version;
- }
- }
- return {};
-}
-
-std::string_view
-CompletedTransactionLogData::get_pp_tls_group() const
-{
- if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED) {
- if (auto group = m_http_sm->t_state.pp_info.get_tlv_ssl_group(); group) {
- return *group;
- }
- }
- return {};
-}
-
-// ===== Server response Transfer-Encoding =====
-
-std::string_view
-CompletedTransactionLogData::get_server_response_transfer_encoding() const
-{
- return m_http_sm->t_state.hdr_info.server_response_transfer_encoding;
-}
diff --git a/src/proxy/http/HttpBodyFactory.cc
b/src/proxy/http/HttpBodyFactory.cc
index 05849b781e..cdaaac582d 100644
--- a/src/proxy/http/HttpBodyFactory.cc
+++ b/src/proxy/http/HttpBodyFactory.cc
@@ -40,7 +40,7 @@
#include "proxy/hdrs/URL.h"
#include "proxy/logging/Log.h"
#include "proxy/logging/LogAccess.h"
-#include "proxy/http/CompletedTransactionLogData.h"
+#include "proxy/logging/TransactionLogData.h"
#include "proxy/hdrs/HttpCompat.h"
#include "tscore/Layout.h"
@@ -1158,8 +1158,8 @@
HttpBodyTemplate::build_instantiated_buffer(HttpTransact::State *context, int64_
Dbg(dbg_ctl_body_factory_instantiation, " before instantiation: [%s]",
template_buffer);
- CompletedTransactionLogData log_data(context->state_machine);
- LogAccess la(log_data);
+ TransactionLogData log_data(context->state_machine);
+ LogAccess la(log_data);
buffer = resolve_logfield_string(&la, template_buffer);
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index 524a140574..c75f69ec9d 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -45,7 +45,7 @@
#include "proxy/http/PreWarmConfig.h"
#include "proxy/logging/Log.h"
#include "proxy/logging/LogAccess.h"
-#include "proxy/http/CompletedTransactionLogData.h"
+#include "proxy/logging/TransactionLogData.h"
#include "proxy/PluginVC.h"
#include "proxy/ReverseProxy.h"
#include "proxy/http/remap/RemapProcessor.h"
@@ -7723,8 +7723,8 @@ HttpSM::kill_this()
//////////////
SMDbg(dbg_ctl_http_seq, "Logging transaction");
if (Log::transaction_logging_enabled() &&
t_state.api_info.logging_enabled) {
- CompletedTransactionLogData log_data(this);
- LogAccess accessor(log_data);
+ TransactionLogData log_data(this);
+ LogAccess accessor(log_data);
int ret = Log::access(&accessor);
@@ -8454,8 +8454,8 @@ HttpSM::do_redirect()
if (redirect_url != nullptr ||
t_state.hdr_info.client_response.field_find(static_cast<std::string_view>(MIME_FIELD_LOCATION)))
{
if (Log::transaction_logging_enabled() &&
t_state.api_info.logging_enabled) {
- CompletedTransactionLogData log_data(this);
- LogAccess accessor(log_data);
+ TransactionLogData log_data(this);
+ LogAccess accessor(log_data);
if (redirect_url == nullptr) {
if (t_state.squid_codes.log_code == SquidLogCode::TCP_HIT) {
t_state.squid_codes.log_code = SquidLogCode::TCP_HIT_REDIRECT;
diff --git a/src/proxy/logging/CMakeLists.txt b/src/proxy/logging/CMakeLists.txt
index bf109bad66..f897952ff2 100644
--- a/src/proxy/logging/CMakeLists.txt
+++ b/src/proxy/logging/CMakeLists.txt
@@ -28,6 +28,7 @@ add_library(
LogFormat.cc
LogFieldFallback.cc
LogObject.cc
+ TransactionLogData.cc
LogUtils.cc
RolledLogDeleter.cc
YamlLogConfig.cc
@@ -37,7 +38,16 @@ add_library(ts::logging ALIAS logging)
target_include_directories(logging PRIVATE ${SWOC_INCLUDE_DIR})
-target_link_libraries(logging PUBLIC ts::inkevent ts::inkutils ts::hdrs
ts::tscore ts::configmanager yaml-cpp::yaml-cpp)
+target_link_libraries(
+ logging
+ PUBLIC ts::inkevent
+ ts::inkutils
+ ts::http
+ ts::hdrs
+ ts::tscore
+ ts::configmanager
+ yaml-cpp::yaml-cpp
+)
if(BUILD_TESTING)
add_executable(test_LogFieldFallback unit-tests/test_LogFieldFallback.cc)
diff --git a/src/proxy/logging/TransactionLogData.cc
b/src/proxy/logging/TransactionLogData.cc
new file mode 100644
index 0000000000..af44b5e374
--- /dev/null
+++ b/src/proxy/logging/TransactionLogData.cc
@@ -0,0 +1,1117 @@
+/** @file
+
+ TransactionLogData implementation.
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+ */
+
+#include "proxy/logging/TransactionLogData.h"
+#include "proxy/PreTransactionLogData.h"
+#include "proxy/http/HttpSM.h"
+#include "proxy/logging/LogAccess.h"
+#include "proxy/hdrs/MIME.h"
+#include "tscore/ink_defs.h"
+#include "../private/SSLProxySession.h"
+
+namespace
+{
+/** Map HttpTransact::CacheWriteStatus_t to LogCacheWriteCodeType. */
+int
+convert_cache_write_code(HttpTransact::CacheWriteStatus_t t)
+{
+ switch (t) {
+ case HttpTransact::CacheWriteStatus_t::NO_WRITE:
+ return LOG_CACHE_WRITE_NONE;
+ case HttpTransact::CacheWriteStatus_t::LOCK_MISS:
+ return LOG_CACHE_WRITE_LOCK_MISSED;
+ case HttpTransact::CacheWriteStatus_t::IN_PROGRESS:
+ return LOG_CACHE_WRITE_LOCK_ABORTED;
+ case HttpTransact::CacheWriteStatus_t::ERROR:
+ return LOG_CACHE_WRITE_ERROR;
+ case HttpTransact::CacheWriteStatus_t::COMPLETE:
+ return LOG_CACHE_WRITE_COMPLETE;
+ default:
+ ink_assert(!"bad cache write code");
+ return LOG_CACHE_WRITE_NONE;
+ }
+}
+
+int
+compute_client_finish_status(HttpSM *sm)
+{
+ HttpTransact::AbortState_t cl_abort_state = sm->t_state.client_info.abort;
+ if (cl_abort_state == HttpTransact::ABORTED) {
+ if (sm->t_state.client_info.state == HttpTransact::ACTIVE_TIMEOUT ||
+ sm->t_state.client_info.state == HttpTransact::INACTIVE_TIMEOUT) {
+ return LOG_FINISH_TIMEOUT;
+ }
+ return LOG_FINISH_INTR;
+ }
+ return LOG_FINISH_FIN;
+}
+
+int
+compute_proxy_finish_status(HttpSM *sm)
+{
+ if (sm->t_state.current.server) {
+ switch (sm->t_state.current.server->state) {
+ case HttpTransact::ACTIVE_TIMEOUT:
+ case HttpTransact::INACTIVE_TIMEOUT:
+ return LOG_FINISH_TIMEOUT;
+ case HttpTransact::CONNECTION_ERROR:
+ return LOG_FINISH_INTR;
+ default:
+ if (sm->t_state.current.server->abort == HttpTransact::ABORTED) {
+ return LOG_FINISH_INTR;
+ }
+ break;
+ }
+ }
+ return LOG_FINISH_FIN;
+}
+} // end anonymous namespace
+
+TransactionLogData::TransactionLogData(HttpSM *sm) : m_http_sm(sm)
+{
+ ink_assert(sm != nullptr);
+}
+
+TransactionLogData::TransactionLogData(PreTransactionLogData const &pre_data)
: m_pre_data(&pre_data) {}
+
+void *
+TransactionLogData::http_sm_for_plugins() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm;
+ }
+ return nullptr;
+}
+
+// ===== Milestones =====
+
+TransactionMilestones const *
+TransactionLogData::get_milestones() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return &m_http_sm->milestones;
+ }
+ return &m_pre_data->owned_milestones;
+}
+
+// ===== Headers =====
+
+HTTPHdr *
+TransactionLogData::get_client_request() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
+ if (hdr->client_request.valid()) {
+ return &hdr->client_request;
+ }
+ return nullptr;
+ }
+
+ if (m_pre_data->owned_client_request.valid()) {
+ return const_cast<HTTPHdr *>(&m_pre_data->owned_client_request);
+ }
+ return nullptr;
+}
+
+HTTPHdr *
+TransactionLogData::get_proxy_response() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
+ if (hdr->client_response.valid()) {
+ return &hdr->client_response;
+ }
+ }
+ return nullptr;
+}
+
+HTTPHdr *
+TransactionLogData::get_proxy_request() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
+ if (hdr->server_request.valid()) {
+ return &hdr->server_request;
+ }
+ }
+ return nullptr;
+}
+
+HTTPHdr *
+TransactionLogData::get_server_response() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
+ if (hdr->server_response.valid()) {
+ return &hdr->server_response;
+ }
+ }
+ return nullptr;
+}
+
+HTTPHdr *
+TransactionLogData::get_cache_response() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ HttpTransact::HeaderInfo *hdr = &m_http_sm->t_state.hdr_info;
+ if (hdr->cache_response.valid()) {
+ return &hdr->cache_response;
+ }
+ }
+ return nullptr;
+}
+
+// ===== Client request URL / path =====
+
+void
+TransactionLogData::cache_url_strings() const
+{
+ if (m_url_cached) {
+ return;
+ }
+ m_url_cached = true;
+
+ HTTPHdr *client_request = get_client_request();
+ if (client_request) {
+ m_client_req_url_str =
client_request->url_string_get_ref(&m_client_req_url_len);
+ auto path_sv = client_request->path_get();
+ m_client_req_url_path_str = path_sv.data();
+ m_client_req_url_path_len = static_cast<int>(path_sv.length());
+ }
+}
+
+const char *
+TransactionLogData::get_client_req_url_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_url_strings();
+ return m_client_req_url_str;
+ }
+ return m_pre_data->owned_url.empty() ? nullptr :
m_pre_data->owned_url.c_str();
+}
+
+int
+TransactionLogData::get_client_req_url_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_url_strings();
+ return m_client_req_url_len;
+ }
+ return static_cast<int>(m_pre_data->owned_url.size());
+}
+
+const char *
+TransactionLogData::get_client_req_url_path_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_url_strings();
+ return m_client_req_url_path_str;
+ }
+ return m_pre_data->owned_path.empty() ? nullptr :
m_pre_data->owned_path.c_str();
+}
+
+int
+TransactionLogData::get_client_req_url_path_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_url_strings();
+ return m_client_req_url_path_len;
+ }
+ return static_cast<int>(m_pre_data->owned_path.size());
+}
+
+// ===== Proxy response content-type / reason =====
+
+void
+TransactionLogData::cache_content_type() const
+{
+ if (m_content_type_cached) {
+ return;
+ }
+ m_content_type_cached = true;
+
+ HTTPHdr *proxy_response = get_proxy_response();
+ if (proxy_response) {
+ MIMEField *field =
proxy_response->field_find(static_cast<std::string_view>(MIME_FIELD_CONTENT_TYPE));
+ if (field) {
+ auto ct = field->value_get();
+ m_proxy_resp_content_type_str = const_cast<char *>(ct.data());
+ m_proxy_resp_content_type_len = ct.length();
+ } else {
+ constexpr std::string_view hidden_ct{"@Content-Type"};
+ field = proxy_response->field_find(hidden_ct);
+ if (field) {
+ auto ct = field->value_get();
+ m_proxy_resp_content_type_str = const_cast<char *>(ct.data());
+ m_proxy_resp_content_type_len = ct.length();
+ }
+ }
+ auto reason = proxy_response->reason_get();
+ m_proxy_resp_reason_phrase_str = const_cast<char *>(reason.data());
+ m_proxy_resp_reason_phrase_len = static_cast<int>(reason.length());
+ }
+}
+
+char *
+TransactionLogData::get_proxy_resp_content_type_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_content_type();
+ return m_proxy_resp_content_type_str;
+ }
+ return nullptr;
+}
+
+int
+TransactionLogData::get_proxy_resp_content_type_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_content_type();
+ return m_proxy_resp_content_type_len;
+ }
+ return 0;
+}
+
+char *
+TransactionLogData::get_proxy_resp_reason_phrase_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_content_type();
+ return m_proxy_resp_reason_phrase_str;
+ }
+ return nullptr;
+}
+
+int
+TransactionLogData::get_proxy_resp_reason_phrase_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ cache_content_type();
+ return m_proxy_resp_reason_phrase_len;
+ }
+ return 0;
+}
+
+// ===== Unmapped URL =====
+
+char *
+TransactionLogData::get_unmapped_url_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.unmapped_url.valid()) {
+ int len = 0;
+ return m_http_sm->t_state.unmapped_url.string_get_ref(&len);
+ }
+ }
+ return nullptr;
+}
+
+int
+TransactionLogData::get_unmapped_url_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.unmapped_url.valid()) {
+ int len = 0;
+ m_http_sm->t_state.unmapped_url.string_get_ref(&len);
+ return len;
+ }
+ }
+ return 0;
+}
+
+// ===== Cache lookup URL =====
+
+char *
+TransactionLogData::get_cache_lookup_url_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) {
+ int len = 0;
+ return
m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len);
+ }
+ }
+ return nullptr;
+}
+
+int
+TransactionLogData::get_cache_lookup_url_len() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.cache_info.lookup_url_storage.valid()) {
+ int len = 0;
+ m_http_sm->t_state.cache_info.lookup_url_storage.string_get_ref(&len);
+ return len;
+ }
+ }
+ return 0;
+}
+
+// ===== Client addressing =====
+
+sockaddr const *
+TransactionLogData::get_client_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return &m_http_sm->t_state.effective_client_addr.sa;
+ }
+ return &m_pre_data->owned_client_addr.sa;
+}
+
+sockaddr const *
+TransactionLogData::get_client_src_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return &m_http_sm->t_state.client_info.src_addr.sa;
+ }
+ return &m_pre_data->owned_client_src_addr.sa;
+}
+
+sockaddr const *
+TransactionLogData::get_client_dst_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return &m_http_sm->t_state.client_info.dst_addr.sa;
+ }
+ return &m_pre_data->owned_client_dst_addr.sa;
+}
+
+sockaddr const *
+TransactionLogData::get_verified_client_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (auto txn = m_http_sm->get_ua_txn(); txn) {
+ sockaddr const *vaddr = txn->get_verified_client_addr();
+ if (vaddr && ats_is_ip(vaddr)) {
+ return vaddr;
+ }
+ }
+ }
+ return nullptr;
+}
+
+uint16_t
+TransactionLogData::get_client_port() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (auto txn = m_http_sm->get_ua_txn(); txn) {
+ return txn->get_client_port();
+ }
+ return 0;
+ }
+ return m_pre_data->m_client_port;
+}
+
+// ===== Server addressing =====
+
+sockaddr const *
+TransactionLogData::get_server_src_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.current.server) {
+ return &m_http_sm->t_state.current.server->src_addr.sa;
+ }
+ }
+ return nullptr;
+}
+
+sockaddr const *
+TransactionLogData::get_server_dst_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.current.server) {
+ return &m_http_sm->t_state.current.server->dst_addr.sa;
+ }
+ }
+ return nullptr;
+}
+
+sockaddr const *
+TransactionLogData::get_server_info_dst_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return &m_http_sm->t_state.server_info.dst_addr.sa;
+ }
+ return nullptr;
+}
+
+const char *
+TransactionLogData::get_server_name() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.current.server) {
+ return m_http_sm->t_state.current.server->name;
+ }
+ }
+ return nullptr;
+}
+
+// ===== Squid codes =====
+
+SquidLogCode
+TransactionLogData::get_log_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.squid_codes.log_code;
+ }
+ return m_pre_data->m_log_code;
+}
+
+SquidSubcode
+TransactionLogData::get_subcode() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.squid_codes.subcode;
+ }
+ return SquidSubcode::EMPTY;
+}
+
+SquidHitMissCode
+TransactionLogData::get_hit_miss_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.squid_codes.hit_miss_code;
+ }
+ return m_pre_data->m_hit_miss_code;
+}
+
+SquidHierarchyCode
+TransactionLogData::get_hier_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.squid_codes.hier_code;
+ }
+ return m_pre_data->m_hier_code;
+}
+
+// ===== Byte counters =====
+
+int64_t
+TransactionLogData::get_client_request_body_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_request_body_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_client_response_hdr_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_response_hdr_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_client_response_body_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_response_body_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_server_request_body_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_request_body_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_server_response_body_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_response_body_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_cache_response_body_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->cache_response_body_bytes;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_cache_response_hdr_bytes() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->cache_response_hdr_bytes;
+ }
+ return 0;
+}
+
+// ===== Transaction identifiers =====
+
+int64_t
+TransactionLogData::get_sm_id() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->sm_id;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_connection_id() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_connection_id();
+ }
+ return m_pre_data->m_connection_id;
+}
+
+int
+TransactionLogData::get_transaction_id() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_transaction_id();
+ }
+ return m_pre_data->m_transaction_id;
+}
+
+int
+TransactionLogData::get_transaction_priority_weight() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_transaction_priority_weight();
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_transaction_priority_dependence() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->client_transaction_priority_dependence();
+ }
+ return 0;
+}
+
+// ===== Plugin info =====
+
+int64_t
+TransactionLogData::get_plugin_id() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->plugin_id;
+ }
+ return 0;
+}
+
+const char *
+TransactionLogData::get_plugin_tag() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->plugin_tag;
+ }
+ return nullptr;
+}
+
+// ===== Protocol info =====
+
+const char *
+TransactionLogData::get_client_protocol() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_protocol();
+ }
+ return m_pre_data->owned_client_protocol_str.empty() ? nullptr :
m_pre_data->owned_client_protocol_str.c_str();
+}
+
+const char *
+TransactionLogData::get_server_protocol() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_protocol;
+ }
+ return nullptr;
+}
+
+const char *
+TransactionLogData::get_client_sec_protocol() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_sec_protocol();
+ }
+ return nullptr;
+}
+
+const char *
+TransactionLogData::get_client_cipher_suite() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_cipher_suite();
+ }
+ return nullptr;
+}
+
+const char *
+TransactionLogData::get_client_curve() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_curve();
+ }
+ return nullptr;
+}
+
+const char *
+TransactionLogData::get_client_security_group() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_security_group();
+ }
+ return nullptr;
+}
+
+int
+TransactionLogData::get_client_alpn_id() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_alpn_id();
+ }
+ return -1;
+}
+
+// ===== SNI =====
+
+const char *
+TransactionLogData::get_sni_server_name() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (auto txn = m_http_sm->get_ua_txn(); txn) {
+ if (auto ssn = txn->get_proxy_ssn(); ssn) {
+ if (auto ssl = ssn->ssl(); ssl) {
+ return ssl->client_sni_server_name();
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
+// ===== Connection flags =====
+
+bool
+TransactionLogData::get_client_tcp_reused() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_tcp_reused();
+ }
+ return false;
+}
+
+bool
+TransactionLogData::get_client_connection_is_ssl() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_connection_is_ssl();
+ }
+ return m_pre_data->m_client_connection_is_ssl;
+}
+
+bool
+TransactionLogData::get_client_ssl_reused() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_user_agent().get_client_ssl_reused();
+ }
+ return false;
+}
+
+bool
+TransactionLogData::get_is_internal() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->is_internal;
+ }
+ return false;
+}
+
+bool
+TransactionLogData::get_server_connection_is_ssl() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_connection_is_ssl;
+ }
+ return false;
+}
+
+bool
+TransactionLogData::get_server_ssl_reused() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_ssl_reused;
+ }
+ return false;
+}
+
+int
+TransactionLogData::get_server_connection_provided_cert() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_connection_provided_cert;
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_client_provided_cert() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (auto txn = m_http_sm->get_ua_txn(); txn) {
+ if (auto ssn = txn->get_proxy_ssn(); ssn) {
+ if (auto ssl = ssn->ssl(); ssl) {
+ return ssl->client_provided_certificate();
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+// ===== Server transaction count =====
+
+int64_t
+TransactionLogData::get_server_transact_count() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->server_transact_count;
+ }
+ return m_pre_data->m_server_transact_count;
+}
+
+// ===== Finish status =====
+
+int
+TransactionLogData::get_client_finish_status_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return compute_client_finish_status(m_http_sm);
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_proxy_finish_status_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return compute_proxy_finish_status(m_http_sm);
+ }
+ return 0;
+}
+
+// ===== Error codes =====
+
+void
+TransactionLogData::format_error_codes() const
+{
+ if (m_error_codes_formatted) {
+ return;
+ }
+ m_error_codes_formatted = true;
+ ink_assert(m_http_sm != nullptr);
+ m_http_sm->t_state.client_info.rx_error_code.str(m_client_rx_error_code,
sizeof(m_client_rx_error_code));
+ m_http_sm->t_state.client_info.tx_error_code.str(m_client_tx_error_code,
sizeof(m_client_tx_error_code));
+}
+
+const char *
+TransactionLogData::get_client_rx_error_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ format_error_codes();
+ return m_client_rx_error_code;
+ }
+ return "-";
+}
+
+const char *
+TransactionLogData::get_client_tx_error_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ format_error_codes();
+ return m_client_tx_error_code;
+ }
+ return "-";
+}
+
+// ===== MPTCP =====
+
+std::optional<bool>
+TransactionLogData::get_mptcp_state() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->mptcp_state;
+ }
+ return std::nullopt;
+}
+
+// ===== Misc transaction state =====
+
+in_port_t
+TransactionLogData::get_incoming_port() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.request_data.incoming_port;
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_orig_scheme() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.orig_scheme;
+ }
+ return -1;
+}
+
+int64_t
+TransactionLogData::get_congestion_control_crat() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.congestion_control_crat;
+ }
+ return 0;
+}
+
+// ===== Cache state =====
+
+int
+TransactionLogData::get_cache_write_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return
convert_cache_write_code(m_http_sm->t_state.cache_info.write_status);
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_cache_transform_write_code() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return
convert_cache_write_code(m_http_sm->t_state.cache_info.transform_write_status);
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_cache_open_read_tries() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_cache_sm().get_open_read_tries();
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_cache_open_write_tries() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->get_cache_sm().get_open_write_tries();
+ }
+ return 0;
+}
+
+int
+TransactionLogData::get_max_cache_open_write_retries() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.txn_conf->max_cache_open_write_retries;
+ }
+ return -1;
+}
+
+// ===== Retry attempts =====
+
+int64_t
+TransactionLogData::get_simple_retry_attempts() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.current.simple_retry_attempts;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_unavailable_retry_attempts() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.current.unavailable_server_retry_attempts;
+ }
+ return 0;
+}
+
+int64_t
+TransactionLogData::get_retry_attempts_saved() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.current.retry_attempts.saved();
+ }
+ return 0;
+}
+
+// ===== Status plugin entry name =====
+
+std::string_view
+TransactionLogData::get_http_return_code_setter_name() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.http_return_code_setter_name;
+ }
+ return {};
+}
+
+// ===== Proxy Protocol =====
+
+int
+TransactionLogData::get_pp_version() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ return static_cast<int>(m_http_sm->t_state.pp_info.version);
+ }
+ }
+ return 0;
+}
+
+sockaddr const *
+TransactionLogData::get_pp_src_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ return &m_http_sm->t_state.pp_info.src_addr.sa;
+ }
+ }
+ return nullptr;
+}
+
+sockaddr const *
+TransactionLogData::get_pp_dst_addr() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ return &m_http_sm->t_state.pp_info.dst_addr.sa;
+ }
+ }
+ return nullptr;
+}
+
+std::string_view
+TransactionLogData::get_pp_authority() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ if (auto authority_opt =
m_http_sm->t_state.pp_info.get_tlv(PP2_TYPE_AUTHORITY); authority_opt) {
+ return *authority_opt;
+ }
+ }
+ }
+ return {};
+}
+
+std::string_view
+TransactionLogData::get_pp_tls_cipher() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ if (auto cipher = m_http_sm->t_state.pp_info.get_tlv_ssl_cipher();
cipher) {
+ return *cipher;
+ }
+ }
+ }
+ return {};
+}
+
+std::string_view
+TransactionLogData::get_pp_tls_version() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ if (auto version = m_http_sm->t_state.pp_info.get_tlv_ssl_version();
version) {
+ return *version;
+ }
+ }
+ }
+ return {};
+}
+
+std::string_view
+TransactionLogData::get_pp_tls_group() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ if (m_http_sm->t_state.pp_info.version != ProxyProtocolVersion::UNDEFINED)
{
+ if (auto group = m_http_sm->t_state.pp_info.get_tlv_ssl_group(); group) {
+ return *group;
+ }
+ }
+ }
+ return {};
+}
+
+// ===== Server response Transfer-Encoding =====
+
+std::string_view
+TransactionLogData::get_server_response_transfer_encoding() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return m_http_sm->t_state.hdr_info.server_response_transfer_encoding;
+ }
+ return {};
+}
+
+// ===== Fallback fields for pre-transaction logging =====
+
+std::string_view
+TransactionLogData::get_method() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return {};
+ }
+ return m_pre_data->owned_method;
+}
+
+std::string_view
+TransactionLogData::get_scheme() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return {};
+ }
+ return m_pre_data->owned_scheme;
+}
+
+std::string_view
+TransactionLogData::get_client_protocol_str() const
+{
+ if (likely(m_http_sm != nullptr)) {
+ return {};
+ }
+ return m_pre_data->owned_client_protocol_str;
+}
diff --git a/src/proxy/logging/unit-tests/test_LogAccess.cc
b/src/proxy/logging/unit-tests/test_LogAccess.cc
index e567a2889c..aee2bd6728 100644
--- a/src/proxy/logging/unit-tests/test_LogAccess.cc
+++ b/src/proxy/logging/unit-tests/test_LogAccess.cc
@@ -25,6 +25,7 @@
#include "proxy/PreTransactionLogData.h"
#include "proxy/logging/LogAccess.h"
+#include "proxy/logging/TransactionLogData.h"
#include "tscore/ink_inet.h"
#include <string_view>
@@ -167,7 +168,8 @@ TEST_CASE("LogAccess pre-transaction CONNECT fields",
"[LogAccess]")
{
PreTransactionLogData data;
populate_pre_transaction_data(data, "CONNECT", ""sv, "example.com:443",
""sv);
- LogAccess access(data);
+ TransactionLogData log_data(data);
+ LogAccess access(log_data);
access.init();
@@ -187,7 +189,8 @@ TEST_CASE("LogAccess malformed CONNECT without authority
falls back to path", "[
{
PreTransactionLogData data;
populate_pre_transaction_data(data, "CONNECT", "https"sv, ""sv, "/"sv);
- LogAccess access(data);
+ TransactionLogData log_data(data);
+ LogAccess access(log_data);
access.init();
@@ -202,7 +205,8 @@ TEST_CASE("LogAccess pre-transaction client host port is
null-safe", "[LogAccess
{
PreTransactionLogData data;
populate_pre_transaction_data(data, "GET", "https"sv, "example.com",
"/client-port"sv);
- LogAccess access(data);
+ TransactionLogData log_data(data);
+ LogAccess access(log_data);
access.init();