-
-
Notifications
You must be signed in to change notification settings - Fork 261
libpcp_web, pmproxy: support for optional labels #2591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| #!/bin/sh | ||
| # PCP QA Test No. 1744 | ||
| # Test pmproxy / pmseries label storing mechanism | ||
| # | ||
| # Copyright (c) 2026 Red Hat. All Rights Reserved. | ||
| # | ||
| seq=`basename $0` | ||
| echo "QA output created by $seq" | ||
|
|
||
| # get standard environment, filters and checks | ||
| . ./common.openmetrics | ||
| . ./common.python | ||
| . ./common.keys | ||
|
|
||
| _pmdaopenmetrics_check || _notrun "openmetrics pmda not installed" | ||
|
|
||
| test -x $PCP_BINADM_DIR/pmseries_import || _notrun "No pmseries_import script" | ||
| _check_series | ||
|
|
||
| status=1 # failure is the default! | ||
|
|
||
| _cleanup() | ||
| { | ||
| cd $here | ||
| [ -n "$pmloggerpid" ] && $sudo kill -TERM $pmloggerpid 2>/dev/null | ||
| if [ -n "$key_server_port" ]; then | ||
| echo "Shutting down key server on port $key_server_port..." >>$here/$seq.full | ||
| $keys_cli -p $key_server_port shutdown >>$here/$seq.full 2>&1 | ||
| sleep 1 | ||
| # Verify it's actually dead | ||
| if $keys_cli -p $key_server_port PING >>$here/$seq.full 2>&1; then | ||
| echo "WARNING: Key server still running after shutdown!" >>$here/$seq.full | ||
| else | ||
| echo "Key server shutdown confirmed" >>$here/$seq.full | ||
| fi | ||
| fi | ||
| $sudo rm -rf $PCP_ETC_DIR/pcp/labels/* | ||
| _restore_config $PCP_ETC_DIR/pcp/labels | ||
| _sighup_pmcd | ||
| _pmdaopenmetrics_cleanup | ||
| _restore_config $PCP_SYSCONF_DIR/pmseries | ||
| $sudo rm -rf $tmp $tmp.* | ||
| } | ||
|
Comment on lines
+22
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleanup deletes Line 37 unconditionally 🤖 Prompt for AI Agents |
||
|
|
||
| _prepare_pmda openmetrics | ||
| trap "_cleanup; exit \$status" 0 1 2 3 15 | ||
| _stop_auto_restart pmcd | ||
|
|
||
| _filter() | ||
| { | ||
| # Replace machine-specific label values with placeholders | ||
| hostname=`hostname` | ||
| machineid=`_machine_id` | ||
| domainid=`_domain_name` | ||
| sed \ | ||
| -e "s/\"hostname\":\"$hostname\"/\"hostname\":\"HOSTNAME\"/g" \ | ||
| -e "s/\"domainname\":\"$domainid\"/\"domainname\":\"DOMAINNAME\"/g" \ | ||
| -e "s/\"machineid\":\"$machineid\"/\"machineid\":\"MACHINEID\"/g" \ | ||
| -e 's/"groupid":[0-9]*/"groupid":GROUPID/g' \ | ||
| -e 's/"userid":[0-9]*/"userid":USERID/g' | ||
| } | ||
|
|
||
| _filter_series() | ||
| { | ||
| sed \ | ||
| -e 's/[0-9a-z]\{40\}/TIMESERIES/g' \ | ||
| #end | ||
| } | ||
|
|
||
| # real QA test starts here | ||
|
|
||
| key_server_port=`_find_free_port` | ||
| _save_config $PCP_SYSCONF_DIR/pmseries | ||
| $sudo rm -f $PCP_SYSCONF_DIR/pmseries/* | ||
|
|
||
| # Create pmseries config pointing to our test key server | ||
| $sudo tee $PCP_SYSCONF_DIR/pmseries/pmseries.conf > /dev/null <<EOF | ||
| [pmseries] | ||
| servers = localhost:$key_server_port | ||
| EOF | ||
|
|
||
| echo "Start test key server on port $key_server_port..." >>$seq.full | ||
| $key_server --port $key_server_port --save "" > $tmp.keys 2>&1 & | ||
| _check_key_server_ping $key_server_port | ||
| _check_key_server $key_server_port | ||
| echo | ||
|
|
||
| _check_key_server_version $key_server_port | ||
|
|
||
| _pmdaopenmetrics_save_config | ||
| _save_config $PCP_ETC_DIR/pcp/labels | ||
| $sudo rm -rf $PCP_ETC_DIR/pcp/labels/* | ||
|
|
||
| # add the URL for this test | ||
| # need to be a place the user $PCP_USER (pmcd) can read | ||
| # | ||
| file=pmseries_label_test.txt | ||
| cp $here/openmetrics/samples/$file $tmp.$file | ||
| urlbase=`basename "$file" .txt | tr .- _` | ||
| echo 'file://'$tmp.$file >$tmp.tmp | ||
|
|
||
| # add a bunch of label filters to exercise various filtering options | ||
| cat <<EOF >>$tmp.tmp | ||
|
|
||
| FILTER: OPTIONAL LABEL some_optional_label | ||
|
|
||
| EOF | ||
| $sudo cp $tmp.tmp $PCP_PMDAS_DIR/openmetrics/config.d/$urlbase.url | ||
|
Comment on lines
+102
to
+108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Locate openmetrics PMDA FILTER parsing to confirm whether the argument is a label name, value, or regex.
fd -t f 'pmda(openmetrics|.*\.python)' src/pmdas/openmetrics 2>/dev/null
rg -nP -C5 '\bFILTER\s*:?\s*OPTIONAL\b' --type=py --type=sh --type=md
rg -nP -C5 'OPTIONAL\s+LABEL'
rg -nP -C3 'PM_LABEL_OPTIONAL' --type=c --type=pyRepository: performancecopilot/pcp Length of output: 20928 🏁 Script executed: # Find and examine the label test file to confirm label name and value
find . -name "*pmseries_label_test*" -o -name "*label_test*" | head -20Repository: performancecopilot/pcp Length of output: 115 🏁 Script executed: # Search for the actual label name and value in openmetrics samples
rg -n "test_metric2|optional_label" --type=txt --type=py src/pmdas/openmetrics/ qa/Repository: performancecopilot/pcp Length of output: 447 🏁 Script executed: # Look for the filter parsing code in the openmetrics PMDA
fd -t f "openmetrics" src/pmdas/openmetrics/ | grep -E "\.(py|c)$"Repository: performancecopilot/pcp Length of output: 48 🏁 Script executed: # Find the openmetrics PMDA Python implementation
find . -path "*/pmdas/openmetrics*.python" -type fRepository: performancecopilot/pcp Length of output: 113 🏁 Script executed: # Search for the OPTIONAL LABEL filter parsing in Python code
rg -n "OPTIONAL|LABEL" src/pmdas/openmetrics/pmdaopenmetrics.python -A 5 -B 5Repository: performancecopilot/pcp Length of output: 6815 🏁 Script executed: # Check the entire config parsing section
rg -n "FILTER" src/pmdas/openmetrics/pmdaopenmetrics.python -A 3 -B 3 | head -100Repository: performancecopilot/pcp Length of output: 1636 Fix filter to use label name instead of value: change The filter incorrectly uses the label value instead of the label name. The label is defined as Note: The test files contain a comment stating "*** NOTE: optional labels are not implemented yet" — confirm whether this feature is active before merging. 🤖 Prompt for AI Agents |
||
|
|
||
| _pmdaopenmetrics_install | ||
|
|
||
| if ! _pmdaopenmetrics_wait_for_metric openmetrics.control.calls | ||
| then | ||
| status=1 | ||
| exit | ||
| fi | ||
|
|
||
| # Verify metrics are available from PMCD | ||
| echo "Verify openmetrics metrics are available ..." | ||
| pminfo -f openmetrics.pmseries_label_test.test_metric1 #>>$seq_full 2>&1 | ||
| pminfo -f openmetrics.pmseries_label_test.test_metric2 #>>$seq_full 2>&1 | ||
| echo | ||
|
|
||
| # Create a test archive with pmlogger | ||
| echo "Creating test archive with pmlogger ..." | ||
| cat > $tmp.pmlogger.config <<EOF | ||
| log mandatory on once { | ||
| openmetrics.pmseries_label_test | ||
| } | ||
| EOF | ||
| pmlogger -c $tmp.pmlogger.config -l $tmp.pmlogger.log -t 1sec $tmp.archive & | ||
| pmloggerpid=$! | ||
| echo "=== pmlogger started, PID=$pmloggerpid ===" >>$seq_full | ||
|
|
||
| # Wait for pmlogger to capture some data | ||
| pmsleep 3 | ||
|
|
||
| # Stop pmlogger | ||
| $sudo kill -TERM $pmloggerpid 2>/dev/null | ||
| pmsleep 1 | ||
|
|
||
| # Verify archive was created | ||
| echo "Archive files created:" >>$seq_full | ||
| ls -l $tmp.archive* >>$seq_full 2>&1 | ||
|
|
||
| # Check key server port and flush | ||
| echo "Using key server on port $key_server_port" >>$seq_full | ||
| echo "Flushing key server on port $key_server_port ..." | ||
| flush_result=`echo "FLUSHALL" | $keys_cli -p $key_server_port 2>&1` | ||
| echo "Flush result: $flush_result" >>$seq_full | ||
| if [ "$flush_result" != "OK" ]; then | ||
| echo "ERROR: Failed to flush key server, got: $flush_result" | ||
| status=1 | ||
| exit | ||
| fi | ||
| echo "Key server flushed successfully" | ||
|
|
||
| # Load the archive into pmseries | ||
| echo "Loading test archive into pmseries ..." | ||
| pmseries $options --load "{source.path: \"$tmp.archive\"}" 2>&1 | \ | ||
| sed "s|$tmp.archive|ARCHIVE|g" | tee -a $seq_full | ||
|
|
||
| # Wait for metrics to be indexed | ||
| echo "Waiting for metrics to be indexed ..." | ||
| pmsleep 2 | ||
|
|
||
| # Query for the first metric (identifying labels only) | ||
| echo | ||
| echo "=== test_metric1 (identifying labels only) ===" | ||
| series1=`pmseries $options 'openmetrics.pmseries_label_test.test_metric1'` | ||
| if [ -z "$series1" ]; then | ||
| echo "ERROR: No series found for test_metric1" | ||
| status=1 | ||
| else | ||
| pmseries $series1 | _filter_series | _filter | ||
| fi | ||
|
|
||
| # Query for the second metric (with optional label) | ||
| echo | ||
| echo "=== test_metric2 (with optional label) ===" | ||
| series2=`pmseries $options 'openmetrics.pmseries_label_test.test_metric2'` | ||
| if [ -z "$series2" ]; then | ||
| echo "ERROR: No series found for test_metric2" | ||
| status=1 | ||
| else | ||
| pmseries $series2 | _filter_series | _filter | ||
| fi | ||
|
Comment on lines
+170
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test sets If 🐛 Suggested fix-# success, all done
-status=0
-exit
+# success, all done — but only if no earlier ERROR set status=1
+[ "$status" = 1 ] || status=0
+exitOr simpler: track failures with a separate flag and only clear it at the end if no failure occurred. 🤖 Prompt for AI Agents |
||
|
|
||
| echo == Note: check $seq.full for details | ||
| echo == pmdaopenmetrics LOG == >>$seq_full | ||
| cat $PCP_LOG_DIR/pmcd/openmetrics.log >>$seq_full | ||
| echo == pmlogger LOG == >>$seq_full | ||
| cat $tmp.pmlogger.log >>$seq_full 2>&1 | ||
|
|
||
| _pmdaopenmetrics_remove | ||
|
|
||
| # success, all done | ||
| status=0 | ||
| exit | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| QA output created by 1744 | ||
| PING | ||
| PONG | ||
|
|
||
|
|
||
| === openmetrics agent installation === | ||
| Verify openmetrics metrics are available ... | ||
|
|
||
| openmetrics.pmseries_label_test.test_metric1 | ||
| inst [0 or "0 label1:somelabel"] value 1 | ||
|
|
||
| openmetrics.pmseries_label_test.test_metric2 | ||
| inst [0 or "0 label2:somelabel optional_label:some_optional_label"] value 2 | ||
|
|
||
| Creating test archive with pmlogger ... | ||
| Flushing key server on port 54321 ... | ||
| Key server flushed successfully | ||
| Loading test archive into pmseries ... | ||
| pmseries: [Info] processed 3 archive records from ARCHIVE | ||
| Waiting for metrics to be indexed ... | ||
|
|
||
| === test_metric1 (identifying labels only) === | ||
|
|
||
| TIMESERIES | ||
| PMID: 144.1.0 | ||
| Data Type: double InDom: 144.5120 0x24001400 | ||
| Semantics: instant Units: none | ||
| Source: TIMESERIES | ||
| Metric: openmetrics.pmseries_label_test.test_metric1 | ||
| inst [0 or "0 label1:somelabel"] series TIMESERIES | ||
| inst [0 or "0 label1:somelabel"] labels {"agent":"openmetrics","domainname":"DOMAINNAME","groupid":GROUPID,"hostname":"HOSTNAME","machineid":"MACHINEID","source":"pmseries_label_test","userid":USERID} | ||
|
|
||
| === test_metric2 (with optional label) === | ||
|
|
||
| TIMESERIES | ||
| PMID: 144.1.1 | ||
| Data Type: double InDom: 144.5121 0x24001401 | ||
| Semantics: instant Units: none | ||
| Source: TIMESERIES | ||
| Metric: openmetrics.pmseries_label_test.test_metric2 | ||
| inst [0 or "0 label2:somelabel optional_label:some_optional_label"] series TIMESERIES | ||
| inst [0 or "0 label2:somelabel optional_label:some_optional_label"] labels {"agent":"openmetrics","domainname":"DOMAINNAME","groupid":GROUPID,"hostname":"HOSTNAME","machineid":"MACHINEID","source":"pmseries_label_test","userid":USERID} | ||
| == Note: check 1744.full for details | ||
|
|
||
| === remove openmetrics agent === | ||
| Culling the Performance Metrics Name Space ... | ||
| openmetrics ... done | ||
| Updating the PMCD control file, and notifying PMCD ... | ||
| [...removing files...] | ||
| Check openmetrics metrics have gone away ... OK |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| # HELP test_metric1 local metric | ||
| # Type test_metric1 gauge | ||
| test_metric1 {label1="somelabel"} 1 | ||
|
|
||
|
|
||
| # HELP test_metric2 local metric | ||
| # Type test_metric2 gauge | ||
| test_metric2 {label2="somelabel", optional_label="some_optional_label"} 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pmseries_importis checked here but never used.The script loads archives directly via
pmseries $options --load "{source.path: ...}"(line 160), and never invokespmseries_import. This_notrungate will spuriously skip the test on systems that shippmseriesbut notpmseries_import(or are renamed in a future packaging change), without any actual dependency on that tool. Drop the check, or replace it with whatever the test actually depends on (e.g.,pmseriesitself).🧹 Suggested fix
🤖 Prompt for AI Agents