Class: Pvectl::Commands::Logs::Command
- Inherits:
-
Object
- Object
- Pvectl::Commands::Logs::Command
- Defined in:
- lib/pvectl/commands/logs/command.rb,
sig/pvectl/commands/logs/command.rbs
Overview
Dispatcher for the pvectl logs <resource_type> <id> command.
Routes requests to appropriate log handlers:
- vm/ct: task history via Handlers::TaskLogs
- node: syslog via Handlers::Syslog (or journal with --journal)
- task: log lines via Handlers::TaskDetail
Constant Summary collapse
- VM_CT_TYPES =
VM/CT resource types that use TaskLogs handler.
%w[vm vms ct container containers cts].freeze
- NODE_TYPES =
Node resource types.
%w[node nodes].freeze
Class Method Summary collapse
-
.execute(resource_type, resource_id, options, global_options) ⇒ Integer
Executes the logs command.
-
.register(cli) ⇒ void
Registers the logs command with the CLI.
Instance Method Summary collapse
-
#determine_color_enabled ⇒ Boolean
Determines if color output should be enabled.
-
#execute ⇒ Integer
Executes the logs operation.
-
#fetch_data(handler) ⇒ Array<Object>
Fetches data from the handler with appropriate parameters.
-
#format_output(models, presenter) ⇒ String
Formats models for output using the appropriate formatter.
-
#initialize(resource_type, resource_id, options, global_options, handler: nil, journal_handler: nil, registry: Logs::ResourceRegistry) ⇒ Command
constructor
Creates a new Logs command instance.
-
#missing_resource_id_error ⇒ Integer
Outputs error for missing resource ID argument.
-
#missing_resource_type_error ⇒ Integer
Outputs error for missing resource type argument.
-
#resolve_handler ⇒ Object?
Resolves the handler based on resource type and flags.
-
#unknown_resource_error ⇒ Integer
Outputs error for unknown resource type.
Constructor Details
#initialize(resource_type, resource_id, options, global_options, handler: nil, journal_handler: nil, registry: Logs::ResourceRegistry) ⇒ Command
Creates a new Logs command instance.
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/pvectl/commands/logs/command.rb', line 131 def initialize(resource_type, resource_id, , , handler: nil, journal_handler: nil, registry: Logs::ResourceRegistry) @resource_type = resource_type @resource_id = resource_id = = @handler = handler @journal_handler = journal_handler @registry = registry end |
Class Method Details
.execute(resource_type, resource_id, options, global_options) ⇒ Integer
Executes the logs command.
118 119 120 |
# File 'lib/pvectl/commands/logs/command.rb', line 118 def self.execute(resource_type, resource_id, , ) new(resource_type, resource_id, , ).execute end |
.register(cli) ⇒ void
This method returns an undefined value.
Registers the logs command with the CLI.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/pvectl/commands/logs/command.rb', line 27 def self.register(cli) cli.desc "Show logs for resources (task history, syslog, journal)" cli.long_desc " Show logs and task history for cluster resources. The log source\n depends on the resource type:\n\n vm / container Task history (start, stop, backup, migrate, etc.)\n node System log (syslog by default, --journal for systemd)\n task Detailed log output for a specific task UPID\n\n EXAMPLES\n Node syslog (last 50 entries):\n $ pvectl logs node pve1\n\n Node systemd journal:\n $ pvectl logs node pve1 --journal\n\n Task history for a VM:\n $ pvectl logs vm 100\n\n Search VM tasks across all nodes:\n $ pvectl logs vm 100 --all-nodes\n\n Filter by task type and date:\n $ pvectl logs vm 100 --type vzdump --since 2026-01-01\n\n Detailed log for a specific task:\n $ pvectl logs task UPID:pve1:000ABC:...\n\n Filter node syslog by service:\n $ pvectl logs node pve1 --service pvedaemon\n\n Increase entry limit:\n $ pvectl logs node pve1 --limit 200\n\n NOTES\n Default limit is 50 entries. Task detail (UPID) defaults to 512 lines.\n\n --all-nodes searches across every cluster node for VM/CT tasks.\n This is useful when a VM has been migrated between nodes.\n\n Timestamps for --since and --until accept YYYY-MM-DD format\n or Unix epoch seconds.\n\n SEE ALSO\n pvectl help get tasks List task history cluster-wide\n pvectl help describe Detailed resource information\n HELP\n cli.arg_name \"RESOURCE_TYPE ID\"\n cli.command :logs do |c|\n c.desc \"Maximum number of entries to show\"\n c.default_value 50\n c.flag [:limit], type: Integer, arg_name: \"N\"\n\n c.desc \"Show entries since timestamp (YYYY-MM-DD or epoch)\"\n c.flag [:since], arg_name: \"TIMESTAMP\"\n\n c.desc \"Show entries until timestamp (YYYY-MM-DD or epoch)\"\n c.flag [:until], arg_name: \"TIMESTAMP\"\n\n c.desc \"Filter by task type (e.g., qmstart, qmstop, vzdump)\"\n c.flag [:type], arg_name: \"TYPE\"\n\n c.desc \"Filter by status (running, ok, error)\"\n c.flag [:status], arg_name: \"STATUS\"\n\n c.desc \"Filter by service name (syslog only)\"\n c.flag [:service], arg_name: \"SERVICE\"\n\n c.desc \"Use systemd journal instead of syslog (node only)\"\n c.switch [:journal], negatable: false\n\n c.desc \"Search across all cluster nodes (VM/CT only)\"\n c.switch [:\"all-nodes\"], negatable: false\n\n c.action do |global_options, options, args|\n resource_type = args[0]\n resource_id = args[1]\n exit_code = execute(resource_type, resource_id, options, global_options)\n exit exit_code if exit_code != 0\n end\n end\nend\n" |
Instance Method Details
#determine_color_enabled ⇒ Boolean
Determines if color output should be enabled.
266 267 268 269 270 271 |
# File 'lib/pvectl/commands/logs/command.rb', line 266 def determine_color_enabled explicit = [:color] return explicit unless explicit.nil? $stdout.tty? end |
#execute ⇒ Integer
Executes the logs operation.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/pvectl/commands/logs/command.rb', line 146 def execute return missing_resource_type_error if @resource_type.nil? return missing_resource_id_error if @resource_id.nil? || @resource_id.empty? handler = resolve_handler return unknown_resource_error unless handler models = fetch_data(handler) output = format_output(models, handler.presenter) puts output ExitCodes::SUCCESS rescue ResourceNotFoundError => e $stderr.puts "Error: #{e.message}" ExitCodes::NOT_FOUND rescue Pvectl::Config::ConfigNotFoundError, Pvectl::Config::InvalidConfigError, Pvectl::Config::ContextNotFoundError, Pvectl::Config::ClusterNotFoundError, Pvectl::Config::UserNotFoundError => e $stderr.puts "Error: #{e.message}" ExitCodes::CONFIG_ERROR rescue Timeout::Error, Errno::ECONNREFUSED, SocketError => e $stderr.puts "Error: #{e.message}" ExitCodes::CONNECTION_ERROR end |
#fetch_data(handler) ⇒ Array<Object>
Fetches data from the handler with appropriate parameters.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/pvectl/commands/logs/command.rb', line 192 def fetch_data(handler) if VM_CT_TYPES.include?(@resource_type) handler.list( vmid: @resource_id.to_i, resource_type: @resource_type, all_nodes: [:"all-nodes"] || false, limit: [:limit] || 50, since: [:since], until_time: [:until], type_filter: [:type], status_filter: [:status] ) elsif NODE_TYPES.include?(@resource_type) handler.list( node: @resource_id, limit: [:limit] || 50, since: [:since], until_time: [:until], service: [:service] ) elsif @resource_type == "task" handler.list( upid: @resource_id, start: 0, limit: [:limit] || 512 ) else handler.list end end |
#format_output(models, presenter) ⇒ String
Formats models for output using the appropriate formatter.
256 257 258 259 260 261 |
# File 'lib/pvectl/commands/logs/command.rb', line 256 def format_output(models, presenter) format = [:output] || "table" color_enabled = determine_color_enabled formatter = Formatters::Registry.for(format) formatter.format(models, presenter, color_enabled: color_enabled) end |
#missing_resource_id_error ⇒ Integer
Outputs error for missing resource ID argument.
236 237 238 239 240 |
# File 'lib/pvectl/commands/logs/command.rb', line 236 def missing_resource_id_error $stderr.puts "Error: resource ID is required" $stderr.puts "Usage: pvectl logs #{@resource_type} ID [options]" ExitCodes::USAGE_ERROR end |
#missing_resource_type_error ⇒ Integer
Outputs error for missing resource type argument.
226 227 228 229 230 231 |
# File 'lib/pvectl/commands/logs/command.rb', line 226 def missing_resource_type_error $stderr.puts "Error: resource type is required" $stderr.puts "Usage: pvectl logs RESOURCE_TYPE ID [options]" $stderr.puts "Available resources: vm, ct, node, task" ExitCodes::USAGE_ERROR end |
#resolve_handler ⇒ Object?
Resolves the handler based on resource type and flags.
178 179 180 181 182 183 184 185 186 |
# File 'lib/pvectl/commands/logs/command.rb', line 178 def resolve_handler return @handler if @handler if NODE_TYPES.include?(@resource_type) && [:journal] @journal_handler || Handlers::Journal.new else @registry.for(@resource_type) end end |
#unknown_resource_error ⇒ Integer
Outputs error for unknown resource type.
245 246 247 248 249 |
# File 'lib/pvectl/commands/logs/command.rb', line 245 def unknown_resource_error $stderr.puts "Unknown resource type: #{@resource_type}" $stderr.puts "Available resources: vm, ct, node, task" ExitCodes::USAGE_ERROR end |