39 const std::vector<std::string>&
42 static const std::vector<std::string> words{
43 "trajectory",
"pose",
"gripper",
"velocity",
"joint",
44 "torque",
"waypoint",
"frame",
"transform",
"solver",
45 "converged",
"residual",
"iteration",
"timeout",
"retry",
46 "planner",
"collision",
"segment",
"cartesian",
"orientation",
47 "calibration",
"offset",
"threshold",
"controller",
"setpoint",
48 "measurement",
"estimate",
"covariance",
"landmark",
"keyframe",
49 "descriptor",
"match",
"inlier",
"outlier",
"cloud",
50 "voxel",
"octree",
"occupancy",
"path",
"goal",
51 "obstacle",
"footprint",
"odometry",
"drift",
"latency",
52 "buffer",
"queue",
"dropped",
"stale",
"resynced"};
59 randomId(std::mt19937& rng)
61 static const char* digits =
"0123456789abcdef";
62 std::uniform_int_distribution<int> dist(0, 15);
63 std::string id(8,
'0');
66 c = digits[dist(rng)];
78 "Target number of log messages per second, summed over all threads. <= 0 disables "
79 "the component (it then starts but stays silent).");
83 "Number of concurrent sender threads. They share MessagesPerSecond between them.");
87 "Seed for the random message content. 0 picks a seed from the clock and the process "
88 "id, so instances differ; any other value makes the run reproducible.");
93 "Percentage of messages emitted at WARN. Note that WARN and above attach a full "
94 "backtrace, which is by far the largest per-message cost on the sender side.");
96 "ErrorPercent", 2,
"Percentage of messages emitted at ERROR (also backtraced).");
99 "Percentage of messages emitted at VERBOSE. Only visible if "
100 "ArmarX.Verbosity is set to Verbose or Debug.");
105 "Percentage of messages spanning several lines. These are what give the viewer's "
106 "table rows individual heights.");
108 "MultilineMaxLines", 12,
"Upper bound on the line count of a multi-line message.");
114 "TagCount", 4,
"Number of distinct tags to spread the messages over (at least 1).");
119 "If > 0, emit a burst of BurstSize messages every this many milliseconds, on top of "
120 "the steady rate. Use this to exercise the viewer's staging queue rather than only "
121 "its steady-state throughput.");
128 return "LogSpamTest";
134 getProperty(messagesPerSecond,
"MessagesPerSecond");
141 getProperty(multilineMaxLines,
"MultilineMaxLines");
148 threadCount = std::max(1, threadCount);
149 tagCount = std::max(1, tagCount);
150 minWords = std::max(1, minWords);
151 maxWords = std::max(minWords, maxWords);
152 multilineMaxLines = std::max(2, multilineMaxLines);
153 burstSize = std::max(0, burstSize);
157 seed =
static_cast<int>(
158 std::chrono::steady_clock::now().time_since_epoch().count() ^ ::getpid());
161 ARMARX_IMPORTANT <<
"LogSpamTest: " << messagesPerSecond <<
" msg/s over " << threadCount
162 <<
" thread(s), " << warningPercent <<
"% warnings, " << errorPercent
163 <<
"% errors, " << multilinePercent <<
"% multi-line, seed " << seed;
169 if (messagesPerSecond <= 0)
176 for (
int i = 0; i < threadCount; ++i)
179 this, &LogSpamTest::spamTaskRun,
"LogSpamTask" + std::to_string(i)));
182 for (
auto& task : tasks)
192 for (
auto& task : tasks)
208 LogSpamTest::buildMessage(std::mt19937& rng,
long counter)
const
210 const std::vector<std::string>& words = wordPool();
211 std::uniform_int_distribution<std::size_t> wordDist(0, words.size() - 1);
212 std::uniform_int_distribution<int> countDist(minWords, maxWords);
213 std::uniform_int_distribution<int> percentDist(0, 99);
215 std::ostringstream out;
217 out <<
"#" << counter <<
" [" << randomId(rng) <<
"]";
219 const int count = countDist(rng);
220 for (
int i = 0; i < count; ++i)
222 out <<
" " << words[wordDist(rng)];
225 if (percentDist(rng) < multilinePercent)
227 std::uniform_int_distribution<int> lineDist(2, multilineMaxLines);
228 const int lines = lineDist(rng);
229 for (
int line = 0; line < lines; ++line)
231 out <<
"\n " << line <<
": ";
232 const int inner = countDist(rng);
233 for (
int i = 0; i < inner; ++i)
235 out << words[wordDist(rng)] <<
" ";
244 LogSpamTest::emitOne(std::mt19937& rng,
long& counter)
246 const std::string body = buildMessage(rng, counter++);
248 std::uniform_int_distribution<int> percentDist(0, 99);
249 const int roll = percentDist(rng);
251 const std::string
tag =
"spam" + std::to_string(counter % tagCount);
255#define ARMARX_LOG_SPAM(MACRO) MACRO << LogTag(tag) << body
257 if (roll < errorPercent)
261 else if (roll < errorPercent + warningPercent)
265 else if (roll < errorPercent + warningPercent + verbosePercent)
269 else if (roll % 10 == 0)
278#undef ARMARX_LOG_SPAM
282 LogSpamTest::spamTaskRun()
284 const int index = nextThreadIndex++;
285 std::mt19937 rng(
static_cast<std::mt19937::result_type
>(seed +
index * 7919));
289 const int perThreadRate = std::max(1, messagesPerSecond / threadCount);
290 const auto period = std::chrono::nanoseconds(std::chrono::seconds(1)) / perThreadRate;
292 auto nextMessage = std::chrono::steady_clock::now();
293 auto nextBurst = nextMessage + std::chrono::milliseconds(std::max(0, burstEveryMs));
295 while (running.load())
297 emitOne(rng, counter);
299 const auto now = std::chrono::steady_clock::now();
303 if (burstEveryMs > 0 &&
index == 0 && now >= nextBurst)
305 for (
int i = 0; i < burstSize && running.load(); ++i)
307 emitOne(rng, counter);
309 nextBurst = std::chrono::steady_clock::now() +
310 std::chrono::milliseconds(burstEveryMs);
313 nextMessage += period;
314 if (nextMessage < now)
322 std::this_thread::sleep_until(nextMessage);
#define ARMARX_LOG_SPAM(MACRO)
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
Properties of the LogSpamTest component.
LogSpamTestPropertyDefinitions(std::string prefix)
void onInitComponent() override
void onDisconnectComponent() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectComponent() override
void onExitComponent() override
std::string getDefaultName() const override
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
#define ARMARX_INFO
The normal logging level.
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.