1/* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "base/log/dump_log.h" 17 18#include <fstream> 19#include "core/common/ace_application_info.h" 20 21namespace OHOS::Ace { 22 23DumpLog::DumpLog() = default; 24DumpLog::~DumpLog() = default; 25 26void DumpLog::Print(int32_t depth, const std::string& className, int32_t childSize) 27{ 28 if (!ostream_ || !ostream_->good()) { 29 return; 30 } 31 std::string space = " "; 32 for (int32_t i = 0; i < depth; ++i) { 33 ostream_->write(space.c_str(), space.length()); 34 } 35 ostream_->write(space.c_str(), space.length()); 36 std::string data = "|-> "; 37 data.append(className); 38 data.append(" childSize:" + std::to_string(childSize)); 39 data.append("\n"); 40 ostream_->write(data.c_str(), data.length()); 41 for (auto& desc : description_) { 42 for (int32_t i = 0; i < depth; ++i) { 43 ostream_->write(space.c_str(), space.length()); 44 } 45 std::string data = ""; 46 if (childSize == 0) { 47 data = " "; 48 } else { 49 data = " | "; 50 } 51 data.append(desc); 52 ostream_->write(data.c_str(), data.length()); 53 } 54 ostream_->flush(); 55 description_.clear(); 56 description_.shrink_to_fit(); 57} 58 59void DumpLog::Print(const std::string& content) 60{ 61 Print(0, content); 62} 63 64void DumpLog::Print(int32_t depth, const std::string& content) 65{ 66 std::string space = " "; 67 for (int32_t i = 0; i < depth; ++i) { 68 ostream_->write(space.c_str(), space.length()); 69 } 70 std::string data = content + separator_; 71 ostream_->write(data.c_str(), data.length()); 72} 73 74void DumpLog::Reset() 75{ 76 ostream_.reset(); 77} 78 79void DumpLog::ShowDumpHelp(std::vector<std::string>& info) 80{ 81 info.emplace_back(" -element |show element tree"); 82 info.emplace_back(" -render |show render tree"); 83 info.emplace_back(" -inspector |show inspector tree"); 84 info.emplace_back(" -frontend |show path and components count of current page"); 85 info.emplace_back(" -navigation |show navigation path stack"); 86} 87 88void DumpLog::Append(int32_t depth, const std::string& className, int32_t childSize) 89{ 90 for (int32_t i = 0; i < depth; ++i) { 91 result_.append(" "); 92 } 93 result_.append("|-> "); 94 result_.append(className); 95 result_.append(" childSize:" + std::to_string(childSize)); 96 result_.append("\n"); 97 for (auto& desc : description_) { 98 for (int32_t i = 0; i < depth; ++i) { 99 result_.append(" "); 100 } 101 if (childSize == 0) { 102 result_.append(" "); 103 } else { 104 result_.append(" | "); 105 } 106 result_.append(desc); 107 } 108 description_.clear(); 109 description_.shrink_to_fit(); 110} 111 112bool DumpLog::OutPutBySize() 113{ 114 if (!ostream_->good()) { 115 result_.clear(); 116 return false; 117 } 118 // if current result size > max size, dump will output as file 119 if (result_.size() + 1 > DumpLog::MAX_DUMP_LENGTH) { 120 auto dumpFilePath = AceApplicationInfo::GetInstance().GetDataFileDirPath() + "/arkui.dump"; 121 std::unique_ptr<std::ostream> ostream = std::make_unique<std::ofstream>(dumpFilePath); 122 if (!ostream) { 123 result_.clear(); 124 result_.append("Dump output failed,please try again"); 125 ostream_->write(result_.c_str(), result_.length()); 126 result_.clear(); 127 } 128 CHECK_NULL_RETURN(ostream, false); 129 DumpLog::GetInstance().SetDumpFile(std::move(ostream)); 130 } 131 ostream_->write(result_.c_str(), result_.length()); 132 result_.clear(); 133 ostream_->flush(); 134 return true; 135} 136 137void DumpLog::OutPutDefault() 138{ 139 if (!ostream_ || !ostream_->good()) { 140 result_.clear(); 141 return; 142 } 143 ostream_->write(result_.c_str(), result_.length()); 144 result_.clear(); 145 ostream_->flush(); 146} 147 148void DumpLog::PrintJson(const std::string& content) 149{ 150 if (!ostream_->good()) { 151 return; 152 } 153 ostream_->write(content.c_str(), content.length()); 154 ostream_->flush(); 155} 156 157void DumpLog::PrintEndDumpInfoNG(bool isElement) 158{ 159 int32_t depth = GetDepth() + DumpLog::END_POS_TWO; 160 std::string result; 161 for (int32_t i = 0; i < depth; ++i) { 162 result.append("}"); 163 } 164 if (isElement) { 165 Append(result); 166 } else { 167 PrintJson(result); 168 } 169} 170 171std::string DumpLog::GetPrefix(int32_t depth) 172{ 173 std::string prefix = ""; 174 if (depth > 0) { 175 int32_t lastDepth = GetDepth(); 176 if (depth == lastDepth) { 177 prefix.append("},"); 178 } else if (depth > lastDepth) { 179 prefix = ","; 180 } else { 181 int32_t diff = lastDepth - depth + 1; 182 prefix.assign(diff, '}').append(","); 183 } 184 } 185 SetDepth(depth); 186 return prefix; 187} 188 189std::string DumpLog::FormatDumpInfo(const std::string& str, int32_t depth) 190{ 191 if (str.length() > DumpLog::MIN_JSON_LENGTH) { 192 if (depth == 0) { 193 return str.substr(0, str.length() - DumpLog::END_POS_TWO); 194 } 195 return str.substr(1, str.length() - DumpLog::END_POS_THREE); 196 } 197 return str; 198} 199} // namespace OHOS::Ace 200