reporter: Add log output for packaged lm log data
Takes the vector from head to tail of log data and saves it.
This commit is contained in:
		| @@ -7,6 +7,8 @@ | ||||
|  | ||||
| #include <fmt/chrono.h> | ||||
| #include <fmt/format.h> | ||||
| #include <fmt/ostream.h> | ||||
| #include <fmt/time.h> | ||||
| #include <json.hpp> | ||||
|  | ||||
| #include "common/file_util.h" | ||||
| @@ -17,6 +19,7 @@ | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/process.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/lm/manager.h" | ||||
| #include "core/reporter.h" | ||||
| #include "core/settings.h" | ||||
|  | ||||
| @@ -354,6 +357,55 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result, | ||||
|     SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp)); | ||||
| } | ||||
|  | ||||
| void Reporter::SaveLogReport(u32 destination, std::vector<Service::LM::LogMessage> messages) const { | ||||
|     if (!IsReportingEnabled()) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto timestamp = GetTimestamp(); | ||||
|     json out; | ||||
|  | ||||
|     out["yuzu_version"] = GetYuzuVersionData(); | ||||
|     out["report_common"] = | ||||
|         GetReportCommonData(system.CurrentProcess()->GetTitleID(), RESULT_SUCCESS, timestamp); | ||||
|  | ||||
|     out["log_destination"] = | ||||
|         fmt::format("{}", static_cast<Service::LM::DestinationFlag>(destination)); | ||||
|  | ||||
|     auto json_messages = json::array(); | ||||
|     std::transform(messages.begin(), messages.end(), std::back_inserter(json_messages), | ||||
|                    [](const Service::LM::LogMessage& message) { | ||||
|                        json out; | ||||
|                        out["is_head"] = fmt::format("{}", message.header.IsHeadLog()); | ||||
|                        out["is_tail"] = fmt::format("{}", message.header.IsTailLog()); | ||||
|                        out["pid"] = fmt::format("{:016X}", message.header.pid); | ||||
|                        out["thread_context"] = | ||||
|                            fmt::format("{:016X}", message.header.thread_context); | ||||
|                        out["payload_size"] = fmt::format("{:016X}", message.header.payload_size); | ||||
|                        out["flags"] = fmt::format("{:04X}", message.header.flags.Value()); | ||||
|                        out["severity"] = fmt::format("{}", message.header.severity.Value()); | ||||
|                        out["verbosity"] = fmt::format("{:02X}", message.header.verbosity); | ||||
|  | ||||
|                        auto fields = json::array(); | ||||
|                        std::transform(message.fields.begin(), message.fields.end(), | ||||
|                                       std::back_inserter(fields), [](const auto& kv) { | ||||
|                                           json out; | ||||
|                                           out["type"] = fmt::format("{}", kv.first); | ||||
|                                           out["data"] = | ||||
|                                               Service::LM::FormatField(kv.first, kv.second); | ||||
|                                           return std::move(out); | ||||
|                                       }); | ||||
|  | ||||
|                        out["fields"] = std::move(fields); | ||||
|                        return std::move(out); | ||||
|                    }); | ||||
|  | ||||
|     out["log_messages"] = std::move(json_messages); | ||||
|  | ||||
|     SaveToFile(std::move(out), | ||||
|                GetPath("log_report", system.CurrentProcess()->GetTitleID(), timestamp)); | ||||
| } | ||||
|  | ||||
| void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, | ||||
|                                           std::string log_message) const { | ||||
|     if (!IsReportingEnabled()) | ||||
|   | ||||
| @@ -20,6 +20,10 @@ namespace Service::FileSystem { | ||||
| enum class LogMode : u32; | ||||
| } | ||||
|  | ||||
| namespace Service::LM { | ||||
| struct LogMessage; | ||||
| } // namespace Service::LM | ||||
|  | ||||
| namespace Core { | ||||
|  | ||||
| class System; | ||||
| @@ -29,18 +33,22 @@ public: | ||||
|     explicit Reporter(System& system); | ||||
|     ~Reporter(); | ||||
|  | ||||
|     // Used by fatal services | ||||
|     void SaveCrashReport(u64 title_id, ResultCode result, u64 set_flags, u64 entry_point, u64 sp, | ||||
|                          u64 pc, u64 pstate, u64 afsr0, u64 afsr1, u64 esr, u64 far, | ||||
|                          const std::array<u64, 31>& registers, const std::array<u64, 32>& backtrace, | ||||
|                          u32 backtrace_size, const std::string& arch, u32 unk10) const; | ||||
|  | ||||
|     // Used by syscall svcBreak | ||||
|     void SaveSvcBreakReport(u32 type, bool signal_debugger, u64 info1, u64 info2, | ||||
|                             std::optional<std::vector<u8>> resolved_buffer = {}) const; | ||||
|  | ||||
|     // Used by HLE service handler | ||||
|     void SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u32 command_id, | ||||
|                                          const std::string& name, | ||||
|                                          const std::string& service_name) const; | ||||
|  | ||||
|     // Used by stub applet implementation | ||||
|     void SaveUnimplementedAppletReport(u32 applet_id, u32 common_args_version, u32 library_version, | ||||
|                                        u32 theme_color, bool startup_sound, u64 system_tick, | ||||
|                                        std::vector<std::vector<u8>> normal_channel, | ||||
| @@ -51,10 +59,14 @@ public: | ||||
|         New, | ||||
|         System, | ||||
|     }; | ||||
|     // Used by prepo services | ||||
|     void SavePlayReport(u64 title_id, u64 process_id, std::vector<std::vector<u8>> data, | ||||
|                         std::optional<u128> user_id = {}) const; | ||||
|  | ||||
|     void SavePlayReport(PlayReportType type, u64 title_id, std::vector<std::vector<u8>> data, | ||||
|                         std::optional<u64> process_id = {}, std::optional<u128> user_id = {}) const; | ||||
|  | ||||
|     // Used by error applet | ||||
|     void SaveErrorReport(u64 title_id, ResultCode result, | ||||
|                          std::optional<std::string> custom_text_main = {}, | ||||
|                          std::optional<std::string> custom_text_detail = {}) const; | ||||
| @@ -62,6 +74,11 @@ public: | ||||
|     void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode, | ||||
|                                     std::string log_message) const; | ||||
|  | ||||
|     // Used by lm services | ||||
|     void SaveLogReport(u32 destination, std::vector<Service::LM::LogMessage> messages) const; | ||||
|  | ||||
|     // Can be used anywhere to generate a backtrace and general info report at any point during | ||||
|     // execution. Not intended to be used for anything other than debugging or testing. | ||||
|     void SaveUserReport() const; | ||||
|  | ||||
| private: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zach Hilman
					Zach Hilman