This is an automated email from the ASF dual-hosted git repository. zwoop pushed a commit to branch 7.1.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit cd39a6b01a20cc298cc03c0a430f3061b8003e07 Author: Walt Karas <[email protected]> AuthorDate: Wed Sep 6 15:50:41 2017 +0000 Log fields for Connection ID and HTTP/2 Stream ID. (cherry picked from commit ff2c84732d96963c01d35d78892edc623a1b92d1) Conflicts: proxy/logging/LogAccessHttp.h tests/gold_tests/logging/ccid_ctid.test.py --- doc/admin-guide/logging/formatting.en.rst | 27 ++++++++----- proxy/ProxyClientTransaction.h | 5 +++ proxy/http/Http1ClientTransaction.h | 10 +++++ proxy/http2/Http2Stream.h | 6 +++ proxy/logging/Log.cc | 10 +++++ proxy/logging/LogAccess.cc | 10 +++++ proxy/logging/LogAccess.h | 14 ++++--- proxy/logging/LogAccessHttp.cc | 41 ++++++++++++++++++++ proxy/logging/LogAccessHttp.h | 14 ++++--- tests/gold_tests/logging/ccid_ctid.test.py | 9 ++++- tests/gold_tests/logging/ccid_ctid_observer.py | 53 ++++++++++++++++++++++++++ 11 files changed, 176 insertions(+), 23 deletions(-) diff --git a/doc/admin-guide/logging/formatting.en.rst b/doc/admin-guide/logging/formatting.en.rst index 4e4cc0b..bbb3150 100644 --- a/doc/admin-guide/logging/formatting.en.rst +++ b/doc/admin-guide/logging/formatting.en.rst @@ -179,19 +179,28 @@ Connections and Transactions .. _sca: .. _sstc: +.. _ccid: +.. _ctid: The following log fields are used to list various details of connections and transactions between |TS| proxies and origin servers. -===== ====== ================================================================== -Field Source Description -===== ====== ================================================================== -sca Proxy Number of attempts within the current transaction by |TS| - in connecting to the origin server. -sstc Proxy Number of transactions between the |TS| proxy and the origin - server from a single session. Any value greater than zero - indicates connection reuse. -===== ====== ================================================================== +===== ============== ================================================================== +Field Source Description +===== ============== ================================================================== +sca Proxy Number of attempts within the current transaction by |TS| + in connecting to the origin server. +sstc Proxy Number of transactions between the |TS| proxy and the origin + server from a single session. Any value greater than zero + indicates connection reuse. +ccid Client Request Client Connection ID, a non-negative number for a connection, + which is different for all currently-active connections to + clients. +ctid Client Request Client Transaction ID, a non-negative number for a transaction, + which is different for all currently-active transactions on the + same client connection. For client HTTP/2 transactions, this + value is the stream ID for the transaction. +===== ============== ================================================================== .. _admin-logging-fields-content-type: diff --git a/proxy/ProxyClientTransaction.h b/proxy/ProxyClientTransaction.h index f0004f6..522e9da 100644 --- a/proxy/ProxyClientTransaction.h +++ b/proxy/ProxyClientTransaction.h @@ -251,6 +251,11 @@ public: return parent ? parent->protocol_contains(tag_prefix) : nullptr; } + // This function must return a non-negative number that is different for two in-progress transactions with the same parent + // session. + // + virtual int get_transaction_id() const = 0; + protected: protected: ProxyClientSession *parent; diff --git a/proxy/http/Http1ClientTransaction.h b/proxy/http/Http1ClientTransaction.h index 7547f6b..fb23bc7 100644 --- a/proxy/http/Http1ClientTransaction.h +++ b/proxy/http/Http1ClientTransaction.h @@ -169,6 +169,16 @@ public: } void transaction_done() override; + int + get_transaction_id() const override + { + // For HTTP/1 there is only one on-going transaction at a time per session/connection. Therefore, the transaction count can be + // presumed not to increase during the lifetime of a transaction, thus this function will return a consistent unique transaction + // identifier. + // + return get_transact_count(); + } + protected: uint16_t outbound_port; IpAddr outbound_ip4; diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h index 3bc1dab..48043ee 100644 --- a/proxy/http2/Http2Stream.h +++ b/proxy/http2/Http2Stream.h @@ -122,6 +122,12 @@ public: return _id; } + int + get_transaction_id() const override + { + return _id; + } + Http2StreamState get_state() const { diff --git a/proxy/logging/Log.cc b/proxy/logging/Log.cc index 4cddd99..9e06443 100644 --- a/proxy/logging/Log.cc +++ b/proxy/logging/Log.cc @@ -838,6 +838,16 @@ Log::init_fields() global_field_list.add(field, false); ink_hash_table_insert(field_symbol_hash, "fsiz", field); + field = new LogField("client_connection_id", "ccid", LogField::sINT, &LogAccess::marshal_client_http_connection_id, + &LogAccess::unmarshal_int_to_str); + global_field_list.add(field, false); + ink_hash_table_insert(field_symbol_hash, "ccid", field); + + field = new LogField("client_transaction_id", "ctid", LogField::sINT, &LogAccess::marshal_client_http_transaction_id, + &LogAccess::unmarshal_int_to_str); + global_field_list.add(field, false); + ink_hash_table_insert(field_symbol_hash, "ctid", field); + Ptr<LogFieldAliasTable> entry_type_map = make_ptr(new LogFieldAliasTable); entry_type_map->init(N_LOG_ENTRY_TYPES, LOG_ENTRY_HTTP, "LOG_ENTRY_HTTP", LOG_ENTRY_ICP, "LOG_ENTRY_ICP"); field = new LogField("log_entry_type", "etype", LogField::sINT, &LogAccess::marshal_entry_type, &LogAccess::unmarshal_entry_type, diff --git a/proxy/logging/LogAccess.cc b/proxy/logging/LogAccess.cc index 2af4915..144d82a 100644 --- a/proxy/logging/LogAccess.cc +++ b/proxy/logging/LogAccess.cc @@ -489,6 +489,16 @@ LogAccess::marshal_process_uuid(char *buf) /*------------------------------------------------------------------------- -------------------------------------------------------------------------*/ +LOG_ACCESS_DEFAULT_FIELD(marshal_client_http_connection_id, DEFAULT_INT_FIELD) + +/*------------------------------------------------------------------------- + -------------------------------------------------------------------------*/ + +LOG_ACCESS_DEFAULT_FIELD(marshal_client_http_transaction_id, DEFAULT_INT_FIELD) + +/*------------------------------------------------------------------------- + -------------------------------------------------------------------------*/ + int LogAccess::marshal_config_int_var(char *config_var, char *buf) { diff --git a/proxy/logging/LogAccess.h b/proxy/logging/LogAccess.h index a17454b..ad41247 100644 --- a/proxy/logging/LogAccess.h +++ b/proxy/logging/LogAccess.h @@ -268,12 +268,14 @@ public: // other fields // - inkcoreapi virtual int marshal_transfer_time_ms(char *); // INT - inkcoreapi virtual int marshal_transfer_time_s(char *); // INT - inkcoreapi virtual int marshal_file_size(char *); // INT - inkcoreapi virtual int marshal_plugin_identity_id(char *); // INT - inkcoreapi virtual int marshal_plugin_identity_tag(char *); // STR - inkcoreapi virtual int marshal_process_uuid(char *); // STR + inkcoreapi virtual int marshal_transfer_time_ms(char *); // INT + inkcoreapi virtual int marshal_transfer_time_s(char *); // INT + inkcoreapi virtual int marshal_file_size(char *); // INT + inkcoreapi virtual int marshal_plugin_identity_id(char *); // INT + inkcoreapi virtual int marshal_plugin_identity_tag(char *); // STR + inkcoreapi virtual int marshal_process_uuid(char *); // STR + inkcoreapi virtual int marshal_client_http_connection_id(char *); // INT + inkcoreapi virtual int marshal_client_http_transaction_id(char *); // INT // These two are special, in that they are shared for all log types / implementations inkcoreapi int marshal_entry_type(char *); // INT diff --git a/proxy/logging/LogAccessHttp.cc b/proxy/logging/LogAccessHttp.cc index d9a58a1..bb7381a 100644 --- a/proxy/logging/LogAccessHttp.cc +++ b/proxy/logging/LogAccessHttp.cc @@ -1480,6 +1480,47 @@ LogAccessHttp::marshal_file_size(char *buf) -------------------------------------------------------------------------*/ int +LogAccessHttp::marshal_client_http_connection_id(char *buf) +{ + if (buf) { + int64_t id = 0; + if (m_http_sm) { + auto p = m_http_sm->ua_session; + if (p) { + auto p2 = p->get_parent(); + if (p2) { + id = p2->connection_id(); + } + } + } + marshal_int(buf, id); + } + return INK_MIN_ALIGN; +} + +/*------------------------------------------------------------------------- + -------------------------------------------------------------------------*/ + +int +LogAccessHttp::marshal_client_http_transaction_id(char *buf) +{ + if (buf) { + int64_t id = 0; + if (m_http_sm) { + auto p = m_http_sm->ua_session; + if (p) { + id = p->get_transaction_id(); + } + } + marshal_int(buf, id); + } + return INK_MIN_ALIGN; +} + +/*------------------------------------------------------------------------- + -------------------------------------------------------------------------*/ + +int LogAccessHttp::marshal_http_header_field(LogField::Container container, char *field, char *buf) { char *str = nullptr; diff --git a/proxy/logging/LogAccessHttp.h b/proxy/logging/LogAccessHttp.h index 830e5d2..6d4632f 100644 --- a/proxy/logging/LogAccessHttp.h +++ b/proxy/logging/LogAccessHttp.h @@ -147,12 +147,14 @@ public: // // other fields // - virtual int marshal_transfer_time_ms(char *); // INT - virtual int marshal_transfer_time_s(char *); // INT - virtual int marshal_file_size(char *); // INT - virtual int marshal_plugin_identity_id(char *); // INT - virtual int marshal_plugin_identity_tag(char *); // STR - virtual int marshal_cache_lookup_url_canon(char *); // STR + int marshal_transfer_time_ms(char *) override; // INT + int marshal_transfer_time_s(char *) override; // INT + int marshal_file_size(char *) override; // INT + int marshal_plugin_identity_id(char *) override; // INT + int marshal_plugin_identity_tag(char *) override; // STR + int marshal_cache_lookup_url_canon(char *) override; // STR + int marshal_client_http_connection_id(char *) override; // INT + int marshal_client_http_transaction_id(char *) override; // INT // // named fields from within a http header diff --git a/tests/gold_tests/logging/ccid_ctid.test.py b/tests/gold_tests/logging/ccid_ctid.test.py index b990891..ef60083 100644 --- a/tests/gold_tests/logging/ccid_ctid.test.py +++ b/tests/gold_tests/logging/ccid_ctid.test.py @@ -40,7 +40,7 @@ ts.addSSLfile("../remap/ssl/server.key") ts.Variables.ssl_port = 4443 ts.Disk.records_config.update({ - # 'proxy.config.diags.debug.enabled': 1, + # 'proxy.config.diags.debug.enabled': '1', 'proxy.config.ssl.server.cert.path': '{0}'.format(ts.Variables.SSLDir), 'proxy.config.ssl.server.private_key.path': '{0}'.format(ts.Variables.SSLDir), 'proxy.config.http.server_ports': 'ipv4:{0} ipv4:{1}:proto=http2;http:ssl'.format(ts.Variables.port, ts.Variables.ssl_port) @@ -69,9 +69,14 @@ log.ascii { }'''.split("\n") ) +# Ask the OS if the port is ready for connect() +# +def CheckPort(Port): + return lambda: 0 == subprocess.call('netstat --listen --tcp -n | grep -q :{}'.format(Port), shell=True) + tr = Test.AddTestRun() # Delay on readiness of ssl port -tr.Processes.Default.StartBefore(Test.Processes.ts, ready=When.PortOpen(ts.Variables.ssl_port)) +tr.Processes.Default.StartBefore(Test.Processes.ts, ready=CheckPort(ts.Variables.ssl_port)) # tr.Processes.Default.Command = 'curl "http://127.0.0.1:{0}" --verbose'.format( ts.Variables.port) diff --git a/tests/gold_tests/logging/ccid_ctid_observer.py b/tests/gold_tests/logging/ccid_ctid_observer.py new file mode 100644 index 0000000..1b4cee5 --- /dev/null +++ b/tests/gold_tests/logging/ccid_ctid_observer.py @@ -0,0 +1,53 @@ +''' +Examines log generated by ccid_ctid.test.py, returns 0 if valid, 1 if not. +''' +# 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. + +import sys +import csv + +ccid = [] +ctid = [] + +# Read in ccid and ctid fields from each line of the generated report. +# +for ln in csv.reader(sys.stdin, delimiter=' '): + if len(ln) != 2: + exit(code=1) + i = int(ln[0]) + if i < 0: + exit(code=1) + ccid.append(i) + i = int(ln[1]) + if i < 0: + exit(code=1) + ctid.append(i) + +# Validate contents of report. +# +if (ccid[0] != ccid[1] and + ccid[1] != ccid[2] and + ccid[2] == ccid[3] and + ctid[2] != ctid[3] and + ccid[3] != ccid[4] and + ccid[4] == ccid[5] and + ctid[4] != ctid[5]): + exit(code=0) + +# Failure exit if report was not valid. +# +exit(code=1) -- To stop receiving notification emails like this one, please contact [email protected].
