-
Notifications
You must be signed in to change notification settings - Fork 5
Add textfile collector for subordinate info metric #109
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?
Conversation
Abuelodelanada
left a comment
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.
LGTM!
Some minor comments added!
| def _write_node_exporter_textfile(self) -> None: | ||
| """Write a per-unit metrics file for node-exporter's textfile collector. | ||
|
|
||
| The file will contain one or more `subordinate_charm_info` metrics with | ||
| labels identifying the subordinate (this unit) and the principal unit, | ||
| plus juju topology labels. | ||
| """ | ||
| topology = JujuTopology.from_charm(self) | ||
|
|
||
| # Gather principal units from cos-agent and juju-info relations | ||
| principals = set() | ||
| for rel_name in ("cos-agent", "juju-info"): | ||
| for rel in self.model.relations.get(rel_name, []): | ||
| for unit in rel.units: | ||
| principals.add(unit.name) | ||
|
|
||
| # Build metric lines | ||
| lines = [] | ||
| for principal in sorted(principals): | ||
| labels = { | ||
| "subordinate_unit": self.unit.name, | ||
| "principal_unit": principal, | ||
| "juju_model": topology.model, | ||
| "juju_model_uuid": topology.model_uuid, | ||
| } | ||
| # Format labels as key="value" | ||
| label_str = ",".join(f'{k}="{v}"' for k, v in labels.items()) | ||
| lines.append(f"subordinate_charm_info{{{label_str}}} 1") | ||
|
|
||
| LocalPath(NODE_EXPORTER_TEXTFILE_DIR).mkdir(parents=True, exist_ok=True) | ||
| # Filename must match the glob `*.prom` used by node-exporter's textfile collector | ||
| # Ref: https://github.com/prometheus/node_exporter/tree/master?tab=readme-ov-file#textfile-collector | ||
| LocalPath(os.path.join(NODE_EXPORTER_TEXTFILE_DIR, f'{self.unit.name.replace("/", "_")}.prom')).write_text("\n".join(lines) + ("\n" if lines else "")) | ||
|
|
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.
Some separations of concerns:
-
The topology object is already created in line 151, I would remove this responsibility from the method.
-
I would extract the responsibility of generating the set of principal's unit names to another method.
| def _write_node_exporter_textfile(self) -> None: | |
| """Write a per-unit metrics file for node-exporter's textfile collector. | |
| The file will contain one or more `subordinate_charm_info` metrics with | |
| labels identifying the subordinate (this unit) and the principal unit, | |
| plus juju topology labels. | |
| """ | |
| topology = JujuTopology.from_charm(self) | |
| # Gather principal units from cos-agent and juju-info relations | |
| principals = set() | |
| for rel_name in ("cos-agent", "juju-info"): | |
| for rel in self.model.relations.get(rel_name, []): | |
| for unit in rel.units: | |
| principals.add(unit.name) | |
| # Build metric lines | |
| lines = [] | |
| for principal in sorted(principals): | |
| labels = { | |
| "subordinate_unit": self.unit.name, | |
| "principal_unit": principal, | |
| "juju_model": topology.model, | |
| "juju_model_uuid": topology.model_uuid, | |
| } | |
| # Format labels as key="value" | |
| label_str = ",".join(f'{k}="{v}"' for k, v in labels.items()) | |
| lines.append(f"subordinate_charm_info{{{label_str}}} 1") | |
| LocalPath(NODE_EXPORTER_TEXTFILE_DIR).mkdir(parents=True, exist_ok=True) | |
| # Filename must match the glob `*.prom` used by node-exporter's textfile collector | |
| # Ref: https://github.com/prometheus/node_exporter/tree/master?tab=readme-ov-file#textfile-collector | |
| LocalPath(os.path.join(NODE_EXPORTER_TEXTFILE_DIR, f'{self.unit.name.replace("/", "_")}.prom')).write_text("\n".join(lines) + ("\n" if lines else "")) | |
| def _get_principal_units(self) -> set: | |
| # Gather principal units from cos-agent and juju-info relations | |
| principals = set() | |
| for rel_name in ("cos-agent", "juju-info"): | |
| for rel in self.model.relations.get(rel_name, []): | |
| for unit in rel.units: | |
| principals.add(unit.name) | |
| return sorted(principals) | |
| def _write_node_exporter_textfile(self, topology: JujuTopology) -> None: | |
| """Write a per-unit metrics file for node-exporter's textfile collector. | |
| The file will contain one or more `subordinate_charm_info` metrics with | |
| labels identifying the subordinate (this unit) and the principal unit, | |
| plus juju topology labels. | |
| """ | |
| # Gather principal units from cos-agent and juju-info relations | |
| principals = self._get_principal_units() | |
| # Build metric lines | |
| lines = [] | |
| for principal in principals: | |
| labels = { | |
| "subordinate_unit": self.unit.name, | |
| "principal_unit": principal, | |
| "juju_model": topology.model, | |
| "juju_model_uuid": topology.model_uuid, | |
| } | |
| # Format labels as key="value" | |
| label_str = ",".join(f'{k}="{v}"' for k, v in labels.items()) | |
| lines.append(f"subordinate_charm_info{{{label_str}}} 1") | |
| LocalPath(NODE_EXPORTER_TEXTFILE_DIR).mkdir(parents=True, exist_ok=True) | |
| # Filename must match the glob `*.prom` used by node-exporter's textfile collector | |
| # Ref: https://github.com/prometheus/node_exporter/tree/master?tab=readme-ov-file#textfile-collector | |
| LocalPath(os.path.join(NODE_EXPORTER_TEXTFILE_DIR, f'{self.unit.name.replace("/", "_")}.prom')).write_text("\n".join(lines) + ("\n" if lines else "")) | |
| return | ||
|
|
||
| # Update node-exporter textfile collector with info about subordinate relations | ||
| self._write_node_exporter_textfile() |
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.
| self._write_node_exporter_textfile() | |
| self._write_node_exporter_textfile(topology) |
|
Need to demo for @marcusboden with alerts for principal charm that include the charm name (not app). |
Updated the node exporter textfile collector directory to use $SNAP_COMMON. Signed-off-by: Leon <[email protected]>
Signed-off-by: Leon <[email protected]>
3dd1d68 to
9e3cd10
Compare
This PR is a PoC for #108.
Fixes #98.
Fixes #108.
In tandem with:Add read access to /etc/node-exporter node-exporter-snap#19Testing
Deploy the bundle:
Context
Since node-exporter is not necessarily installed when
constants.pyis parsed, the value for $SNAP_COMMON is hard-coded rather than obtained dynamically.