-
Notifications
You must be signed in to change notification settings - Fork 225
PMM-15283 Extend Real-Time Analytics to MySQL #5509
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
Open
theTibi
wants to merge
26
commits into
main
Choose a base branch
from
rta-mysql-test
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 12 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
274b711
feat(rta): extend Real-Time Analytics to MySQL
theTibi 0799543
feat(rta): full processlist raw data + hide-COMMIT toggle for MySQL
theTibi d52d9b1
fix(rta): per-type version gate, latency floor, collector tests + nits
theTibi 93f4012
fix(rta): remove MySQL statement-latency collection floor
theTibi d3e3c47
fix(rta): preflight checks for MySQL collector with clear error status
theTibi bf0391f
fix(rta): address review — 3.9.0 gate, defensive support check, nits
theTibi c3e860b
feat(rta): inventory add/change API + CLI and API tests for MySQL RTA…
theTibi 8b4f967
Merge branch 'main' into rta-mysql-test
theTibi 54ad5d1
Merge remote-tracking branch 'origin/main' into rta-mysql-test
theTibi 48e93be
Merge remote-tracking branch 'origin/main' into rta-mysql-test
theTibi 8465a49
feat(rta): add database and user filters to the overview table
theTibi 433dd46
fix(rta): address CodeRabbit review findings
theTibi 6764b4e
Merge branch 'main' into rta-mysql-test
theTibi f281253
fix(rta): guard nil pmm-agent version; fix stale processlist doc
theTibi 6e2d77a
feat(rta): pin Elapsed time to the right edge of the overview table
theTibi 4a57085
chore(rta): align generated files with make gen output
theTibi 1e03295
fix(rta): resolve golangci-lint findings in new RTA MySQL code
theTibi df2a3b3
feat(rta): implement comma-separated filter for Database and User col…
theTibi 45a36bb
PMM-15283 Hide Database/User columns by default and compact Elapsed time
theTibi 2b15eef
Merge branch 'main' into rta-mysql-test
theTibi d1740fc
PMM-15283 Keep millisecond precision in RTA Elapsed time
theTibi c7ca4cb
PMM-15283 Mark RTA technology, drop hand-pinning, scope Hide COMMIT
theTibi df1c662
Merge branch 'main' into rta-mysql-test
theTibi 570998d
PMM-15283 Harden the MySQL RTA collector loop
theTibi 84442d6
Merge branch 'main' into rta-mysql-test
theTibi bb3e1c7
Merge branch 'main' into rta-mysql-test
theTibi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| // Copyright (C) 2023 Percona LLC | ||
| // | ||
| // Licensed 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. | ||
|
|
||
| package inventory | ||
|
|
||
| import ( | ||
| "time" | ||
|
|
||
| "github.com/percona/pmm/admin/commands" | ||
| "github.com/percona/pmm/admin/pkg/flags" | ||
| "github.com/percona/pmm/api/inventory/v1/json/client" | ||
| agents "github.com/percona/pmm/api/inventory/v1/json/client/agents_service" | ||
| ) | ||
|
|
||
| var addAgentRTAMySQLAgentResultT = commands.ParseTemplate(` | ||
| Real-Time Analytics MySQL agent added. | ||
| Agent ID : {{ .Agent.AgentID }} | ||
| PMM-Agent ID : {{ .Agent.PMMAgentID }} | ||
| Service ID : {{ .Agent.ServiceID }} | ||
| Username : {{ .Agent.Username }} | ||
| TLS enabled : {{ .Agent.TLS }} | ||
| Skip TLS verification : {{ .Agent.TLSSkipVerify }} | ||
|
|
||
| Disabled : {{ .Agent.Disabled }} | ||
| Custom labels : {{ formatCustomLabels .Agent.CustomLabels }} | ||
| Collect interval : {{ .Agent.RtaOptions.CollectInterval }} | ||
| Log level : {{ formatLogLevel .Agent.LogLevel }} | ||
| `) | ||
|
|
||
| type addAgentRTAMySQLAgentResult struct { | ||
| Agent *agents.AddAgentOKBodyRtaMysqlAgent `json:"rta_mysql_agent"` | ||
| } | ||
|
|
||
| func (res *addAgentRTAMySQLAgentResult) Result() {} | ||
|
|
||
| func (res *addAgentRTAMySQLAgentResult) String() string { | ||
| return commands.RenderTemplate(addAgentRTAMySQLAgentResultT, res) | ||
| } | ||
|
|
||
| // AddAgentRTAMySQLAgentCommand is used by Kong for CLI flags and commands. | ||
| type AddAgentRTAMySQLAgentCommand struct { | ||
| PMMAgentID string `arg:"" help:"The pmm-agent identifier which runs this instance"` | ||
| ServiceID string `arg:"" help:"Service identifier"` | ||
| Username string `arg:"" optional:"" help:"MySQL username for getting queries data"` | ||
| Password string `help:"MySQL password for getting queries data"` | ||
| CustomLabels map[string]string `mapsep:"," help:"Custom user-assigned labels"` | ||
| SkipConnectionCheck bool `help:"Skip connection check"` | ||
| TLS bool `help:"Use TLS to connect to the database"` | ||
| TLSSkipVerify bool `help:"Skip TLS certificate verification"` | ||
| TLSCaFile string `help:"Path to certificate authority file"` | ||
| TLSCertFile string `help:"Path to client certificate file"` | ||
| TLSKeyFile string `help:"Path to client key file"` | ||
| CollectInterval *time.Duration `placeholder:"DURATION" help:"Query collect interval (default: server-defined 2s)"` | ||
|
|
||
| flags.LogLevelFatalFlags | ||
| } | ||
|
|
||
| // RunCmd executes the AddAgentRTAMySQLAgentCommand and returns the result. | ||
| func (cmd *AddAgentRTAMySQLAgentCommand) RunCmd() (commands.Result, error) { | ||
| customLabels := commands.ParseKeyValuePair(&cmd.CustomLabels) | ||
|
|
||
| tlsCa, err := commands.ReadFile(cmd.TLSCaFile) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| tlsCert, err := commands.ReadFile(cmd.TLSCertFile) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| tlsKey, err := commands.ReadFile(cmd.TLSKeyFile) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| params := &agents.AddAgentParams{ | ||
| Body: agents.AddAgentBody{ | ||
| RtaMysqlAgent: &agents.AddAgentParamsBodyRtaMysqlAgent{ | ||
| PMMAgentID: cmd.PMMAgentID, | ||
| ServiceID: cmd.ServiceID, | ||
| Username: cmd.Username, | ||
| Password: cmd.Password, | ||
| CustomLabels: *customLabels, | ||
| SkipConnectionCheck: cmd.SkipConnectionCheck, | ||
| TLS: cmd.TLS, | ||
| TLSSkipVerify: cmd.TLSSkipVerify, | ||
| TLSCa: tlsCa, | ||
| TLSCert: tlsCert, | ||
| TLSKey: tlsKey, | ||
| LogLevel: cmd.LogLevel.EnumValue(), | ||
| }, | ||
| }, | ||
| Context: commands.Ctx, | ||
| } | ||
|
|
||
| if cmd.CollectInterval != nil { | ||
| params.Body.RtaMysqlAgent.RtaOptions = &agents.AddAgentParamsBodyRtaMysqlAgentRtaOptions{ | ||
| CollectInterval: cmd.CollectInterval.String(), | ||
| } | ||
| } | ||
|
|
||
| resp, err := client.Default.AgentsService.AddAgent(params) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| return &addAgentRTAMySQLAgentResult{ | ||
| Agent: resp.Payload.RtaMysqlAgent, | ||
| }, nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,221 @@ | ||
| // Copyright (C) 2023 Percona LLC | ||
| // | ||
| // Licensed 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. | ||
|
|
||
| package inventory | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "time" | ||
|
|
||
| "github.com/percona/pmm/admin/commands" | ||
| "github.com/percona/pmm/admin/pkg/flags" | ||
| "github.com/percona/pmm/api/inventory/v1/json/client" | ||
| agents "github.com/percona/pmm/api/inventory/v1/json/client/agents_service" | ||
| ) | ||
|
|
||
| var changeAgentRTAMySQLAgentResultT = commands.ParseTemplate(` | ||
| Real-Time Analytics MySQL agent configuration updated. | ||
| Agent ID : {{ .Agent.AgentID }} | ||
| PMM-Agent ID : {{ .Agent.PMMAgentID }} | ||
| Service ID : {{ .Agent.ServiceID }} | ||
| Username : {{ .Agent.Username }} | ||
| TLS enabled : {{ .Agent.TLS }} | ||
| Skip TLS verification : {{ .Agent.TLSSkipVerify }} | ||
|
|
||
| Disabled : {{ .Agent.Disabled }} | ||
| Custom labels : {{ formatCustomLabels .Agent.CustomLabels }} | ||
| Collect interval : {{ .Agent.RtaOptions.CollectInterval }} | ||
| Log level : {{ formatLogLevel .Agent.LogLevel }} | ||
|
|
||
| {{- if .Changes}} | ||
| Configuration changes applied: | ||
| {{- range .Changes}} | ||
| - {{ . }} | ||
| {{- end}} | ||
| {{- end}} | ||
| `) | ||
|
|
||
| type changeAgentRTAMySQLAgentResult struct { | ||
| Agent *agents.ChangeAgentOKBodyRtaMysqlAgent `json:"rta_mysql_agent"` | ||
| Changes []string `json:"changes,omitempty"` | ||
| } | ||
|
|
||
| func (res *changeAgentRTAMySQLAgentResult) Result() {} | ||
|
|
||
| func (res *changeAgentRTAMySQLAgentResult) String() string { | ||
| return commands.RenderTemplate(changeAgentRTAMySQLAgentResultT, res) | ||
| } | ||
|
|
||
| // ChangeAgentRTAMySQLAgentCommand is used by Kong for CLI flags and commands. | ||
| type ChangeAgentRTAMySQLAgentCommand struct { | ||
| // Embedded flags | ||
| flags.LogLevelFatalChangeFlags | ||
|
|
||
| AgentID string `arg:"" help:"Real-Time Analytics MySQL Agent ID"` | ||
|
|
||
| // NOTE: Only provided flags will be changed, others will remain unchanged | ||
|
|
||
| // Basic options | ||
| Enable *bool `help:"Enable or disable the agent"` | ||
| Username *string `help:"MySQL username for getting queries data"` | ||
| Password *string `help:"MySQL password for getting queries data"` | ||
|
|
||
| // TLS options | ||
| TLS *bool `help:"Use TLS to connect to the database"` | ||
| TLSSkipVerify *bool `help:"Skip TLS certificate verification"` | ||
| TLSCaFile *string `help:"Path to certificate authority file"` | ||
| TLSCertFile *string `help:"Path to client certificate file"` | ||
| TLSKeyFile *string `help:"Path to client key file"` | ||
|
|
||
| // RTA specific options | ||
| CollectInterval *time.Duration `placeholder:"DURATION" help:"Query collect interval (default: server-defined 2s)"` | ||
|
|
||
| // Custom labels | ||
| CustomLabels *map[string]string `mapsep:"," help:"Custom user-assigned labels"` | ||
|
|
||
| SkipConnectionCheck *bool `help:"Skip connection check"` | ||
| } | ||
|
|
||
| // RunCmd executes the ChangeAgentRTAMySQLAgentCommand and returns the result. | ||
| func (cmd *ChangeAgentRTAMySQLAgentCommand) RunCmd() (commands.Result, error) { | ||
| var changes []string | ||
|
|
||
| // Parse custom labels if provided | ||
| customLabels := commands.ParseKeyValuePair(cmd.CustomLabels) | ||
|
|
||
| // Read TLS files if provided | ||
| var tlsCa, tlsCert, tlsKey *string | ||
|
|
||
| if cmd.TLSCaFile != nil { | ||
| content, err := commands.ReadFile(*cmd.TLSCaFile) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to read TLS CA file: %w", err) | ||
| } | ||
|
|
||
| tlsCa = &content | ||
| } | ||
|
|
||
| if cmd.TLSCertFile != nil { | ||
| content, err := commands.ReadFile(*cmd.TLSCertFile) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to read TLS certificate file: %w", err) | ||
| } | ||
|
|
||
| tlsCert = &content | ||
| } | ||
|
|
||
| if cmd.TLSKeyFile != nil { | ||
| content, err := commands.ReadFile(*cmd.TLSKeyFile) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to read TLS key file: %w", err) | ||
| } | ||
|
|
||
| tlsKey = &content | ||
| } | ||
|
|
||
| body := &agents.ChangeAgentParamsBodyRtaMysqlAgent{ | ||
| Enable: cmd.Enable, | ||
| Username: cmd.Username, | ||
| Password: cmd.Password, | ||
| TLS: cmd.TLS, | ||
| TLSSkipVerify: cmd.TLSSkipVerify, | ||
| TLSCa: tlsCa, | ||
| TLSCert: tlsCert, | ||
| TLSKey: tlsKey, | ||
| LogLevel: convertLogLevelPtr(cmd.LogLevel), | ||
| SkipConnectionCheck: cmd.SkipConnectionCheck, | ||
| } | ||
|
|
||
| if customLabels != nil { | ||
| body.CustomLabels = &agents.ChangeAgentParamsBodyRtaMysqlAgentCustomLabels{ | ||
| Values: *customLabels, | ||
| } | ||
| } | ||
|
|
||
| if cmd.CollectInterval != nil { | ||
| body.RtaOptions = &agents.ChangeAgentParamsBodyRtaMysqlAgentRtaOptions{ | ||
| CollectInterval: cmd.CollectInterval.String(), | ||
| } | ||
| } | ||
|
|
||
| params := &agents.ChangeAgentParams{ | ||
| AgentID: cmd.AgentID, | ||
| Body: agents.ChangeAgentBody{ | ||
| RtaMysqlAgent: body, | ||
| }, | ||
| Context: commands.Ctx, | ||
| } | ||
|
|
||
| resp, err := client.Default.AgentsService.ChangeAgent(params) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| // Track changes | ||
| if cmd.Enable != nil { | ||
| if *cmd.Enable { | ||
| changes = append(changes, "enabled agent") | ||
| } else { | ||
| changes = append(changes, "disabled agent") | ||
| } | ||
| } | ||
| if cmd.Username != nil { | ||
| changes = append(changes, "updated username") | ||
| } | ||
| if cmd.Password != nil { | ||
| changes = append(changes, "updated password") | ||
| } | ||
| if cmd.TLS != nil { | ||
| if *cmd.TLS { | ||
| changes = append(changes, "enabled TLS") | ||
| } else { | ||
| changes = append(changes, "disabled TLS") | ||
| } | ||
| } | ||
| if cmd.TLSSkipVerify != nil { | ||
| if *cmd.TLSSkipVerify { | ||
| changes = append(changes, "enabled TLS skip verification") | ||
| } else { | ||
| changes = append(changes, "disabled TLS skip verification") | ||
| } | ||
| } | ||
| if cmd.TLSCaFile != nil { | ||
| changes = append(changes, "updated TLS CA certificate") | ||
| } | ||
| if cmd.TLSCertFile != nil { | ||
| changes = append(changes, "updated TLS certificate") | ||
| } | ||
| if cmd.TLSKeyFile != nil { | ||
| changes = append(changes, "updated TLS key") | ||
| } | ||
| if cmd.LogLevel != nil { | ||
| changes = append(changes, fmt.Sprintf("changed log level to %s", *cmd.LogLevel)) | ||
| } | ||
| if customLabels != nil { | ||
| if len(*customLabels) != 0 { | ||
| changes = append(changes, "updated custom labels") | ||
| } else { | ||
| changes = append(changes, "custom labels are removed") | ||
| } | ||
| } | ||
|
|
||
| if cmd.CollectInterval != nil { | ||
| changes = append(changes, fmt.Sprintf("changed collect interval to %s", *cmd.CollectInterval)) | ||
| } | ||
|
|
||
| return &changeAgentRTAMySQLAgentResult{ | ||
| Agent: resp.Payload.RtaMysqlAgent, | ||
| Changes: changes, | ||
| }, nil | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: percona/pmm
Length of output: 7994
🏁 Script executed:
Repository: percona/pmm
Length of output: 47124
🏁 Script executed:
Repository: percona/pmm
Length of output: 50368
🏁 Script executed (no clone):
Length of output: 298
Guard
RtaOptionsbefore renderingCollectInterval. A missingRtaOptionscausescommands.RenderTemplateto panic with a nil-pointer evaluation error. Apply the same conditional guard in both templates.📍 Affects 2 files
admin/commands/inventory/add_agent_rta_mysql.go#L26-L39(this comment)admin/commands/inventory/change_agent_rta_mysql.go#L27-L39🤖 Prompt for AI Agents