You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bn...@apache.org on 2022/11/15 19:35:13 UTC
[trafficserver] branch master updated: Traffic Dump: Allow unlimited disk utilization (#9186)
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 9e0257e27 Traffic Dump: Allow unlimited disk utilization (#9186)
9e0257e27 is described below
commit 9e0257e27bc51dfefa9740a70404fe46d26fd561
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Tue Nov 15 13:35:07 2022 -0600
Traffic Dump: Allow unlimited disk utilization (#9186)
The traffic_dump.so plugin has a --limit argument that specifies how
much disk space the plugin will use before stopping writing out new
sessions to replay files. This patch allows the user to configure
unrestricted disk utilization by not using the --limit argument which
was previous a required argument.
---
doc/admin-guide/plugins/traffic_dump.en.rst | 3 +-
plugins/experimental/traffic_dump/session_data.cc | 36 ++++++---
plugins/experimental/traffic_dump/session_data.h | 19 ++++-
plugins/experimental/traffic_dump/traffic_dump.cc | 12 ++-
.../pluginTest/traffic_dump/traffic_dump.test.py | 93 +++++++++++++++++++++-
.../traffic_dump/traffic_dump_http3.test.py | 2 +-
.../traffic_dump/traffic_dump_sni_filter.test.py | 6 +-
7 files changed, 148 insertions(+), 23 deletions(-)
diff --git a/doc/admin-guide/plugins/traffic_dump.en.rst b/doc/admin-guide/plugins/traffic_dump.en.rst
index 9b213438f..67bee34d1 100644
--- a/doc/admin-guide/plugins/traffic_dump.en.rst
+++ b/doc/admin-guide/plugins/traffic_dump.en.rst
@@ -46,7 +46,7 @@ Plugin Configuration
.. option:: --limit <N>
- (`required`) - Specifies the max disk usage to N bytes (approximate). Traffic Dump will stop capturing new sessions once disk usage exceeds this limit.
+ (`optional`) - Specifies the maximum disk usage to N bytes (approximate). Traffic Dump will stop capturing new sessions once disk usage exceeds this limit. If this option is not used then no disk utilization limit will be enforced.
.. option:: --sensitive-fields <field1,field2,...,fieldn>
@@ -62,6 +62,7 @@ Plugin Configuration
* ``traffic_ctl plugin msg traffic_dump.sample N`` - changes the sampling ratio N as mentioned above.
* ``traffic_ctl plugin msg traffic_dump.reset`` - resets the disk usage counter.
* ``traffic_ctl plugin msg traffic_dump.limit N`` - changes the max disk usage to N bytes as mentioned above.
+ * ``traffic_ctl plugin msg traffic_dump.unlimit`` - configure Traffic Dump to not enforce a disk usage limit.
Replay Format
=============
diff --git a/plugins/experimental/traffic_dump/session_data.cc b/plugins/experimental/traffic_dump/session_data.cc
index 7179b1cec..eceb9d4cc 100644
--- a/plugins/experimental/traffic_dump/session_data.cc
+++ b/plugins/experimental/traffic_dump/session_data.cc
@@ -151,6 +151,7 @@ int SessionData::session_arg_index = -1;
std::atomic<int64_t> SessionData::sample_pool_size = default_sample_pool_size;
std::atomic<int64_t> SessionData::max_disk_usage = default_max_disk_usage;
std::atomic<int64_t> SessionData::disk_usage = 0;
+std::atomic<bool> SessionData::enforce_disk_limit = default_enforce_disk_limit;
ts::file::path SessionData::log_directory{default_log_directory};
uint64_t SessionData::session_counter = 0;
std::string SessionData::sni_filter;
@@ -174,18 +175,27 @@ SessionData::reset_disk_usage()
disk_usage = 0;
}
+void
+SessionData::disable_disk_limit_enforcement()
+{
+ enforce_disk_limit = false;
+}
+
void
SessionData::set_max_disk_usage(int64_t new_max_disk_usage)
{
- max_disk_usage = new_max_disk_usage;
+ enforce_disk_limit = true;
+ max_disk_usage = new_max_disk_usage;
}
bool
-SessionData::init(std::string_view log_directory, int64_t max_disk_usage, int64_t sample_size, std::string_view ip_filter)
+SessionData::init(std::string_view log_directory, bool enforce_disk_limit, int64_t max_disk_usage, int64_t sample_size,
+ std::string_view ip_filter)
{
- SessionData::log_directory = log_directory;
- SessionData::max_disk_usage = max_disk_usage;
- SessionData::sample_pool_size = sample_size;
+ SessionData::log_directory = log_directory;
+ SessionData::max_disk_usage = max_disk_usage;
+ SessionData::enforce_disk_limit = enforce_disk_limit;
+ SessionData::sample_pool_size = sample_size;
if (!ip_filter.empty()) {
client_ip_filter.emplace();
@@ -210,16 +220,20 @@ SessionData::init(std::string_view log_directory, int64_t max_disk_usage, int64_
TSHttpHookAdd(TS_HTTP_SSN_CLOSE_HOOK, ssncont);
TSDebug(debug_tag, "Initialized with log directory: %s", SessionData::log_directory.c_str());
- TSDebug(debug_tag, "Initialized with sample pool size %" PRId64 " bytes and disk limit %" PRId64 " bytes", sample_size,
- max_disk_usage);
+ if (!SessionData::enforce_disk_limit) {
+ TSDebug(debug_tag, "Initialized with sample pool size of %" PRId64 " bytes and unlimited disk utilization", sample_size);
+ } else {
+ TSDebug(debug_tag, "Initialized with sample pool size of %" PRId64 " bytes and disk limit of %" PRId64 " bytes", sample_size,
+ max_disk_usage);
+ }
return true;
}
bool
-SessionData::init(std::string_view log_directory, int64_t max_disk_usage, int64_t sample_size, std::string_view ip_filter,
- std::string_view sni_filter)
+SessionData::init(std::string_view log_directory, bool enforce_disk_limit, int64_t max_disk_usage, int64_t sample_size,
+ std::string_view ip_filter, std::string_view sni_filter)
{
- if (!init(log_directory, max_disk_usage, sample_size, ip_filter)) {
+ if (!init(log_directory, enforce_disk_limit, max_disk_usage, sample_size, ip_filter)) {
return false;
}
SessionData::sni_filter = sni_filter;
@@ -464,7 +478,7 @@ SessionData::global_session_handler(TSCont contp, TSEvent event, void *edata)
if (this_session_count % sample_pool_size != 0) {
TSDebug(debug_tag, "Ignore session %" PRId64 " per the random sampling mechanism", id);
break;
- } else if (disk_usage >= max_disk_usage) {
+ } else if (enforce_disk_limit && disk_usage >= max_disk_usage) {
TSDebug(debug_tag, "Ignore session %" PRId64 " due to disk usage %" PRId64 " bytes", id, disk_usage.load());
break;
} else {
diff --git a/plugins/experimental/traffic_dump/session_data.h b/plugins/experimental/traffic_dump/session_data.h
index 2c4e3345d..094f02e5b 100644
--- a/plugins/experimental/traffic_dump/session_data.h
+++ b/plugins/experimental/traffic_dump/session_data.h
@@ -50,6 +50,8 @@ public:
static constexpr int64_t default_sample_pool_size = 1000;
/// By default, logging will stop after 10 MB have been dumped.
static constexpr int64_t default_max_disk_usage = 10 * 1000 * 1000;
+ /// By default, do not enforce disk utilization limits.
+ static constexpr bool default_enforce_disk_limit = false;
private:
//
@@ -92,10 +94,12 @@ private:
/// be dumped.
static std::atomic<int64_t> sample_pool_size;
/// The maximum space logs should take up before stopping the dumping of new
- /// sessions.
+ /// sessions. This is only enforced if enforce_disk_limit is true.
static std::atomic<int64_t> max_disk_usage;
/// The amount of bytes currently written to dump files.
static std::atomic<int64_t> disk_usage;
+ /// Whether to enforce a disk utilization limit.
+ static std::atomic<bool> enforce_disk_limit;
/// The directory into which to put the dump files.
static ts::file::path log_directory;
@@ -120,9 +124,10 @@ public:
*
* @return True if initialization is successful, false otherwise.
*/
- static bool init(std::string_view log_directory, int64_t max_disk_usage, int64_t sample_size, std::string_view ip_filter);
- static bool init(std::string_view log_directory, int64_t max_disk_usage, int64_t sample_size, std::string_view ip_filter,
- std::string_view sni_filter);
+ static bool init(std::string_view log_directory, bool enforce_disk_limit, int64_t max_disk_usage, int64_t sample_size,
+ std::string_view ip_filter);
+ static bool init(std::string_view log_directory, bool enforce_disk_limit, int64_t max_disk_usage, int64_t sample_size,
+ std::string_view ip_filter, std::string_view sni_filter);
/** Set the sample_pool_size to a new value.
*
@@ -133,6 +138,12 @@ public:
/** Reset the disk usage counter to 0. */
static void reset_disk_usage();
+ /** Disable disk usage enforcement.
+ *
+ * @param[in] new_max_disk_usage The new value to set for max_disk_usage.
+ */
+ static void disable_disk_limit_enforcement();
+
/** Set the max_disk_usage to a new value.
*
* @param[in] new_max_disk_usage The new value to set for max_disk_usage.
diff --git a/plugins/experimental/traffic_dump/traffic_dump.cc b/plugins/experimental/traffic_dump/traffic_dump.cc
index e348d7da3..3a392f65b 100644
--- a/plugins/experimental/traffic_dump/traffic_dump.cc
+++ b/plugins/experimental/traffic_dump/traffic_dump.cc
@@ -50,6 +50,9 @@ global_message_handler(TSCont contp, TSEvent event, void *edata)
} else if (tag == "reset") {
TSDebug(debug_tag, "TS_EVENT_LIFECYCLE_MSG: Received Msg to reset disk usage counter");
SessionData::reset_disk_usage();
+ } else if (tag == "unlimit") {
+ TSDebug(debug_tag, "TS_EVENT_LIFECYCLE_MSG: Received Msg to disable disk usage limit enforcement");
+ SessionData::disable_disk_limit_enforcement();
} else if (tag == "limit" && msg->data_size) {
const auto new_max_disk_usage = static_cast<int64_t>(strtol(static_cast<char const *>(msg->data), nullptr, 0));
TSDebug(debug_tag, "TS_EVENT_LIFECYCLE_MSG: Received Msg to change max disk usage to %" PRId64 "bytes", new_max_disk_usage);
@@ -87,6 +90,7 @@ TSPluginInit(int argc, char const *argv[])
ts::file::path log_dir{traffic_dump::SessionData::default_log_directory};
int64_t sample_pool_size = traffic_dump::SessionData::default_sample_pool_size;
int64_t max_disk_usage = traffic_dump::SessionData::default_max_disk_usage;
+ bool enforce_disk_limit = traffic_dump::SessionData::default_enforce_disk_limit;
std::string sni_filter;
std::string client_ip_filter;
@@ -143,7 +147,8 @@ TSPluginInit(int argc, char const *argv[])
break;
}
case 'm': {
- max_disk_usage = static_cast<int64_t>(std::strtol(optarg, nullptr, 0));
+ max_disk_usage = static_cast<int64_t>(std::strtol(optarg, nullptr, 0));
+ enforce_disk_limit = true;
break;
}
case '4':
@@ -165,12 +170,13 @@ TSPluginInit(int argc, char const *argv[])
log_dir = ts::file::path(TSInstallDirGet()) / log_dir;
}
if (sni_filter.empty()) {
- if (!traffic_dump::SessionData::init(log_dir.view(), max_disk_usage, sample_pool_size, client_ip_filter)) {
+ if (!traffic_dump::SessionData::init(log_dir.view(), enforce_disk_limit, max_disk_usage, sample_pool_size, client_ip_filter)) {
TSError("[%s] Failed to initialize session state.", traffic_dump::debug_tag);
return;
}
} else {
- if (!traffic_dump::SessionData::init(log_dir.view(), max_disk_usage, sample_pool_size, client_ip_filter, sni_filter)) {
+ if (!traffic_dump::SessionData::init(log_dir.view(), enforce_disk_limit, max_disk_usage, sample_pool_size, client_ip_filter,
+ sni_filter)) {
TSError("[%s] Failed to initialize session state with an SNI filter.", traffic_dump::debug_tag);
return;
}
diff --git a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py
index 7007cf19d..5c1aa6b2d 100644
--- a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py
+++ b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump.test.py
@@ -38,7 +38,7 @@ server = Test.MakeVerifierServerProcess(
# Define ATS and configure it.
-ts = Test.MakeATSProcess("ts", enable_tls=True)
+ts = Test.MakeATSProcess("ts", command='traffic_manager', enable_tls=True)
replay_dir = os.path.join(ts.RunDirectory, "ts", "log")
ts.addSSLfile("ssl/server.pem")
@@ -101,7 +101,7 @@ ts.Disk.traffic_out.Content = Testers.ContainsExpression(
f"Initialized with log directory: {replay_dir}",
"Verify traffic_dump initialized with the configured directory.")
ts.Disk.traffic_out.Content += Testers.ContainsExpression(
- "Initialized with sample pool size 1 bytes and disk limit 1000000000 bytes",
+ "Initialized with sample pool size of 1 bytes and disk limit of 1000000000 bytes",
"Verify traffic_dump initialized with the configured disk limit.")
ts.Disk.traffic_out.Content += Testers.ContainsExpression(
"Finish a session with log file of.*bytes",
@@ -134,6 +134,20 @@ ts.Disk.File(replay_file_session_10, exists=True)
replay_file_session_11 = os.path.join(replay_dir, "127", "000000000000000a")
ts.Disk.File(replay_file_session_11, exists=True)
+# The following will not be written to disk because of a restricted disk limit.
+replay_file_session_12 = os.path.join(replay_dir, "127", "000000000000000b")
+ts.Disk.File(replay_file_session_12, exists=False)
+
+# The following will be written to disk because the disk restriction will be
+# removed.
+replay_file_session_13 = os.path.join(replay_dir, "127", "000000000000000c")
+ts.Disk.File(replay_file_session_13, exists=True)
+
+# The following will not be written to disk because the restriction will be
+# re-added.
+replay_file_session_14 = os.path.join(replay_dir, "127", "000000000000000d")
+ts.Disk.File(replay_file_session_14, exists=False)
+
# Run our test traffic.
tr = Test.AddTestRun("Run the test traffic.")
tr.AddVerifierClientProcess(
@@ -317,3 +331,78 @@ tr.Processes.Default.Command = \
tr.Processes.Default.ReturnCode = 0
tr.StillRunningAfter = server
tr.StillRunningAfter = ts
+
+#
+# Test 10: Verify that we can change the --limit value.
+#
+tr = Test.AddTestRun("Verify changing --limit via traffic_ctl.")
+tr.Processes.Default.Command = "traffic_ctl plugin msg traffic_dump.limit 0"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
+
+tr = Test.AddTestRun("Run some more test traffic with the restricted disk limit.")
+tr.AddVerifierClientProcess(
+ "client-2", replay_file, http_ports=[ts.Variables.port],
+ https_ports=[ts.Variables.ssl_port],
+ ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem",
+ other_args='--keys 1')
+
+# Since the limit is zero, we should not see any new replay file created.
+tr = Test.AddTestRun("Verify no new traffic was dumped")
+# Sleep 2 seconds to give the replay plugin plenty of time to write the file.
+tr.Processes.Default.Command = "sleep 2"
+tr.Processes.Default.ReturnCode = 0
+file = tr.Disk.File(replay_file_session_12)
+file.Exists = False
+
+#
+# Test 11: Verify that we can remove the disk limit.
+#
+tr = Test.AddTestRun("Removing the disk limit via traffic_ctl.")
+tr.Processes.Default.Command = "traffic_ctl plugin msg traffic_dump.unlimit"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
+
+tr = Test.AddTestRun("Run some more test traffic with no disk limit.")
+tr.AddVerifierClientProcess(
+ "client-3", replay_file, http_ports=[ts.Variables.port],
+ https_ports=[ts.Variables.ssl_port],
+ ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem",
+ other_args='--keys 1')
+
+# Since the limit is zero, we should not see any new replay file created.
+tr = Test.AddTestRun("Verify the new traffic was dumped")
+# Sleep 2 seconds to give the replay plugin plenty of time to write the file.
+tr.Processes.Default.Command = "sleep 2"
+tr.Processes.Default.ReturnCode = 0
+file = tr.Disk.File(replay_file_session_13)
+file.Exists = True
+
+#
+# Test 11: Verify that we can again restrict the disk limit.
+#
+# Verify that the restriction can be re-added after unlimit was set. This
+# verifies correct handling of the boolean controlling unlimited disk space.
+#
+tr = Test.AddTestRun("Verify re-adding --limit via traffic_ctl.")
+tr.Processes.Default.Command = "traffic_ctl plugin msg traffic_dump.limit 0"
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Env = ts.Env
+tr.StillRunningAfter = ts
+
+tr = Test.AddTestRun("Run test traffic with newly restricted disk limit.")
+tr.AddVerifierClientProcess(
+ "client-4", replay_file, http_ports=[ts.Variables.port],
+ https_ports=[ts.Variables.ssl_port],
+ ssl_cert="ssl/server_combined.pem", ca_cert="ssl/signer.pem",
+ other_args='--keys 1')
+
+# Since the limit is zero, we should not see any new replay file created.
+tr = Test.AddTestRun("Verify no new traffic was dumped")
+# Sleep 2 seconds to give the replay plugin plenty of time to write the file.
+tr.Processes.Default.Command = "sleep 2"
+tr.Processes.Default.ReturnCode = 0
+file = tr.Disk.File(replay_file_session_14)
+file.Exists = False
diff --git a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_http3.test.py b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_http3.test.py
index fa67411ad..48268b21a 100644
--- a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_http3.test.py
+++ b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_http3.test.py
@@ -105,7 +105,7 @@ ts.Disk.traffic_out.Content = Testers.ContainsExpression(
f"Initialized with log directory: {ts_log_dir}",
"Verify traffic_dump initialized with the configured directory.")
ts.Disk.traffic_out.Content += Testers.ContainsExpression(
- "Initialized with sample pool size 1 bytes and disk limit 1000000000 bytes",
+ "Initialized with sample pool size of 1 bytes and disk limit of 1000000000 bytes",
"Verify traffic_dump initialized with the configured disk limit.")
ts.Disk.traffic_out.Content += Testers.ContainsExpression(
"Finish a session with log file of.*bytes",
diff --git a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py
index b3222cc67..6999293a4 100644
--- a/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py
+++ b/tests/gold_tests/pluginTest/traffic_dump/traffic_dump_sni_filter.test.py
@@ -74,7 +74,7 @@ ts.Disk.sni_yaml.AddLines([
# Configure traffic_dump's SNI filter to only dump connections with SNI bob.com.
sni_filter = "bob.com"
ts.Disk.plugin_config.AddLine(
- f'traffic_dump.so --logdir {replay_dir} --sample 1 --limit 1000000000 '
+ f'traffic_dump.so --logdir {replay_dir} --sample 1 '
f'--sni-filter "{sni_filter}"'
)
@@ -87,6 +87,10 @@ ts.Disk.traffic_out.Content += Testers.ContainsExpression(
"Ignore HTTPS session with non-filtered SNI: dave",
"Verify that the non-desired SNI session was filtered out.")
+ts.Disk.traffic_out.Content += Testers.ContainsExpression(
+ "Initialized with sample pool size of 1 bytes and unlimited disk utilization",
+ "Verify traffic_dump initialized with the configured disk limit.")
+
# Set up the json replay file expectations.
replay_file_session_1 = os.path.join(replay_dir, "127", "0000000000000000")
ts.Disk.File(replay_file_session_1, exists=True)