Skip to content

Commit f5a2e8a

Browse files
committed
feat(cli): add production logs command
2 parents 137fc9e + d1b012c commit f5a2e8a

11 files changed

Lines changed: 1258 additions & 0 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
*
3+
* @file LogsCommand.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*/
13+
#ifndef VIX_LOGS_COMMAND_HPP
14+
#define VIX_LOGS_COMMAND_HPP
15+
16+
#include <string>
17+
#include <vector>
18+
19+
namespace vix::commands
20+
{
21+
/**
22+
* @brief Command entry point for production logs management.
23+
*/
24+
struct LogsCommand
25+
{
26+
/**
27+
* @brief Run the logs command.
28+
*
29+
* Supported forms:
30+
*
31+
* `vix logs`
32+
* `vix logs app`
33+
* `vix logs proxy`
34+
* `vix logs errors`
35+
*
36+
* Options:
37+
*
38+
* `--follow`
39+
* `--errors`
40+
* `--since <value>`
41+
* `--lines <n>`
42+
* `-n <n>`
43+
*
44+
* @param args Command arguments after `logs`.
45+
* @return Process exit code.
46+
*/
47+
static int run(const std::vector<std::string> &args);
48+
49+
/**
50+
* @brief Print logs command help.
51+
*
52+
* @return Process exit code.
53+
*/
54+
static int help();
55+
};
56+
}
57+
58+
#endif
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
*
3+
* @file LogsConfig.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*/
13+
#ifndef VIX_LOGS_CONFIG_HPP
14+
#define VIX_LOGS_CONFIG_HPP
15+
16+
#include <vix/cli/commands/logs/LogsTypes.hpp>
17+
18+
#include <optional>
19+
#include <string>
20+
21+
namespace vix::commands::logs
22+
{
23+
/**
24+
* @brief Read the current Vix project name.
25+
*
26+
* The project name is resolved from `vix.json` when available.
27+
* If no project name is found, the implementation may fall back to
28+
* the current directory name.
29+
*
30+
* @return The detected project name, or std::nullopt if no name can be resolved.
31+
*/
32+
std::optional<std::string> read_project_name();
33+
34+
/**
35+
* @brief Load production logs configuration from vix.json.
36+
*
37+
* The configuration is read from `production.logs`.
38+
*
39+
* Fallbacks:
40+
* - service name from `production.logs.service`
41+
* - then `production.deploy.service`
42+
* - then `production.service.name`
43+
* - then project name
44+
*
45+
* @return Loaded logs configuration.
46+
*/
47+
LogsConfig load_logs_config();
48+
49+
/**
50+
* @brief Apply command-line logs options to the loaded config.
51+
*
52+
* @param cfg Loaded logs configuration.
53+
* @param options Runtime logs options.
54+
* @return Effective logs configuration.
55+
*/
56+
LogsConfig apply_logs_options(
57+
LogsConfig cfg,
58+
const LogsOptions &options);
59+
}
60+
61+
#endif
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
*
3+
* @file LogsOutput.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*/
13+
#ifndef VIX_LOGS_OUTPUT_HPP
14+
#define VIX_LOGS_OUTPUT_HPP
15+
16+
#include <vix/cli/commands/logs/LogsTypes.hpp>
17+
18+
#include <iosfwd>
19+
#include <string>
20+
21+
namespace vix::commands::logs::output
22+
{
23+
/**
24+
* @brief Print the production logs configuration summary.
25+
*
26+
* @param out Output stream.
27+
* @param cfg Effective logs configuration.
28+
* @param options Runtime logs options.
29+
*/
30+
void print_summary(
31+
std::ostream &out,
32+
const LogsConfig &cfg,
33+
const LogsOptions &options);
34+
35+
/**
36+
* @brief Print the beginning of a logs step.
37+
*
38+
* @param out Output stream.
39+
* @param label Step label.
40+
*/
41+
void step(
42+
std::ostream &out,
43+
const std::string &label);
44+
45+
/**
46+
* @brief Print the command that will be executed.
47+
*
48+
* @param out Output stream.
49+
* @param command Command text.
50+
*/
51+
void command(
52+
std::ostream &out,
53+
const std::string &command);
54+
55+
/**
56+
* @brief Print a successful logs message.
57+
*
58+
* @param out Output stream.
59+
* @param message Message to print.
60+
*/
61+
void ok(
62+
std::ostream &out,
63+
const std::string &message);
64+
65+
/**
66+
* @brief Print a logs warning message.
67+
*
68+
* @param out Output stream.
69+
* @param message Message to print.
70+
*/
71+
void warn(
72+
std::ostream &out,
73+
const std::string &message);
74+
75+
/**
76+
* @brief Print a logs error message.
77+
*
78+
* @param out Output stream.
79+
* @param message Message to print.
80+
*/
81+
void error(
82+
std::ostream &out,
83+
const std::string &message);
84+
85+
/**
86+
* @brief Print a fix suggestion.
87+
*
88+
* @param out Output stream.
89+
* @param message Fix suggestion.
90+
*/
91+
void fix(
92+
std::ostream &out,
93+
const std::string &message);
94+
}
95+
96+
#endif
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
*
3+
* @file LogsRunner.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*/
13+
#ifndef VIX_LOGS_RUNNER_HPP
14+
#define VIX_LOGS_RUNNER_HPP
15+
16+
#include <vix/cli/commands/logs/LogsTypes.hpp>
17+
18+
namespace vix::commands::logs::runner
19+
{
20+
/**
21+
* @brief Execute the production logs workflow.
22+
*
23+
* @param cfg Effective logs configuration.
24+
* @param options Runtime logs options.
25+
* @return Process exit code.
26+
*/
27+
int run(
28+
const LogsConfig &cfg,
29+
const LogsOptions &options);
30+
}
31+
32+
#endif
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
*
3+
* @file LogsTypes.hpp
4+
* @author Gaspard Kirira
5+
*
6+
* Copyright 2026, Gaspard Kirira. All rights reserved.
7+
* https://github.com/vixcpp/vix
8+
* Use of this source code is governed by a MIT license
9+
* that can be found in the License file.
10+
*
11+
* Vix.cpp
12+
*/
13+
#ifndef VIX_LOGS_TYPES_HPP
14+
#define VIX_LOGS_TYPES_HPP
15+
16+
#include <filesystem>
17+
#include <string>
18+
19+
namespace vix::commands::logs
20+
{
21+
/**
22+
* @enum LogsTarget
23+
* @brief Target selected by `vix logs`.
24+
*/
25+
enum class LogsTarget
26+
{
27+
All,
28+
App,
29+
Proxy,
30+
Errors
31+
};
32+
33+
/**
34+
* @struct LogsOptions
35+
* @brief Runtime options passed from the logs command line.
36+
*/
37+
struct LogsOptions
38+
{
39+
/**
40+
* @brief Selected log target.
41+
*/
42+
LogsTarget target{LogsTarget::All};
43+
44+
/**
45+
* @brief Follow logs live.
46+
*/
47+
bool follow{false};
48+
49+
/**
50+
* @brief Show only errors.
51+
*/
52+
bool errorsOnly{false};
53+
54+
/**
55+
* @brief Number of lines to show.
56+
*/
57+
int lines{120};
58+
59+
/**
60+
* @brief Optional systemd time filter.
61+
*
62+
* Example:
63+
* "1 hour ago"
64+
*/
65+
std::string since{};
66+
};
67+
68+
/**
69+
* @struct LogsConfig
70+
* @brief Production logs configuration.
71+
*/
72+
struct LogsConfig
73+
{
74+
/**
75+
* @brief Application name.
76+
*/
77+
std::string appName{"vix-app"};
78+
79+
/**
80+
* @brief systemd service name used for app logs.
81+
*/
82+
std::string serviceName{};
83+
84+
/**
85+
* @brief Nginx access log path.
86+
*/
87+
std::filesystem::path nginxAccessLog{};
88+
89+
/**
90+
* @brief Nginx error log path.
91+
*/
92+
std::filesystem::path nginxErrorLog{};
93+
94+
/**
95+
* @brief Default number of lines to show.
96+
*/
97+
int lines{120};
98+
};
99+
}
100+
101+
#endif

src/CLI.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <vix/cli/commands/ProxyCommand.hpp>
5454
#include <vix/cli/commands/HealthCommand.hpp>
5555
#include <vix/cli/commands/DeployCommand.hpp>
56+
#include <vix/cli/commands/LogsCommand.hpp>
5657
#include <vix/cli/commands/AgentCommand.hpp>
5758
#include <vix/cli/commands/GameExportCommand.hpp>
5859
#include <vix/utils/Env.hpp>
@@ -296,6 +297,8 @@ namespace vix
296297
{ return commands::HealthCommand::run(args); };
297298
commands_["deploy"] = [](auto args)
298299
{ return commands::DeployCommand::run(args); };
300+
commands_["logs"] = [](auto args)
301+
{ return commands::LogsCommand::run(args); };
299302
commands_["agent"] = [](auto args)
300303
{ return commands::AgentCommand::run(args); };
301304
commands_["game"] = [](auto args)
@@ -530,6 +533,8 @@ namespace vix
530533
return commands::HealthCommand::help();
531534
if (cmd == "deploy")
532535
return commands::DeployCommand::help();
536+
if (cmd == "logs")
537+
return commands::LogsCommand::help();
533538
if (cmd == "modules")
534539
return commands::ModulesCommand::help();
535540
if (cmd == "game")
@@ -656,6 +661,7 @@ namespace vix
656661
out << indent(3) << "proxy Generate and validate reverse proxy configs\n";
657662
out << indent(3) << "health Check local, public and WebSocket app health\n";
658663
out << indent(3) << "deploy Run the production deployment workflow\n";
664+
out << indent(3) << "logs Show production app and proxy logs\n";
659665
out << indent(3) << "modules Manage optional project modules\n\n";
660666

661667
out << indent(2) << "Registry and dependencies:\n";

0 commit comments

Comments
 (0)