1 /* 2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 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 #ifndef TRANCE_FILE_WRITER_H 16 #define TRANCE_FILE_WRITER_H 17 18 #include <cstdint> 19 #include <fstream> 20 #include <google/protobuf/message_lite.h> 21 #include <mutex> 22 #include <queue> 23 #include <string> 24 #include <sys/mman.h> 25 #include "logging.h" 26 #include "nocopyable.h" 27 #include "plugin_module_api.h" 28 #include "trace_file_helper.h" 29 #include "writer.h" 30 31 using google::protobuf::MessageLite; 32 33 #ifndef MMAP_FAILED 34 #define MMAP_FAILED (reinterpret_cast<void *>(-1)) 35 #endif 36 37 class TraceFileWriter : public Writer { 38 public: 39 explicit TraceFileWriter(const std::string& path); 40 explicit TraceFileWriter(int32_t fd); 41 42 explicit TraceFileWriter(const std::string& path, bool splitFile, uint32_t splitFileMaxSizeMb, 43 uint32_t splitFileMaxNum); 44 45 ~TraceFileWriter(); 46 47 std::string Path() const; 48 49 bool SetPluginConfig(const void* data, size_t size); 50 51 void WriteStandalonePluginData(const std::string& pluginName, 52 const std::string& data, 53 const std::string& pluginVersion = ""); 54 55 bool WriteHeader(); 56 57 long Write(const MessageLite& message); 58 59 long Write(const void* data, size_t size) override; 60 61 long WriteStandalonePluginFile(const std::string& file, 62 const std::string& name, 63 const std::string& version, DataType type); 64 65 bool Flush() override; 66 67 bool Finish(); 68 69 bool IsSplitFile(uint32_t size); 70 71 void SetStopSplitFile(bool isStop); 72 73 void SetTimeSource(); 74 void SetDurationTime(); 75 bool UpdateSaFileHeader(); 76 77 private: 78 void SetTimeStamp(); 79 80 void LogDiskUsage(); 81 82 void DeleteOldSplitFile(); 83 84 bool FlushStream(); 85 86 bool GetMemory(uint32_t size, uint8_t** memory, uint32_t* offset); 87 bool Seek(uint32_t offset); 88 bool RemapFile(); 89 90 struct TraceFileWriterCtx { 91 RandomWriteCtx ctx; 92 TraceFileWriter* write; 93 }; 94 GetCtx()95 RandomWriteCtx* GetCtx() override 96 { 97 return &writeCtx_.ctx; 98 } 99 void ResetPos() override; 100 void FinishReport(int32_t size) override; 101 102 private: 103 std::string path_ {}; 104 std::string oldPath_ {}; 105 std::ofstream stream_ {}; 106 uint64_t writeBytes_ = 0; 107 uint64_t writeCount_ = 0; 108 TraceFileHeader header_ {}; 109 TraceFileHelper helper_ {}; 110 uint32_t dataSize_ = 0; 111 bool isSplitFile_ = false; 112 uint32_t splitFileMaxSize_ = 0; 113 uint32_t splitFileMaxNum_ = 0; 114 std::queue<std::string> splitFilePaths_; 115 std::vector<std::vector<char>> pluginConfigsData_; 116 bool isStop_ = false; 117 int fileNum_ = 0; 118 TraceFileHeader::HeaderData headerDataTime_ = {}; // used to store the clock source and collection time. 119 int32_t fd_{-1}; 120 TraceFileWriterCtx writeCtx_ {}; 121 void* fileMapAddr_ = MAP_FAILED; 122 size_t fileLength_ = 0; 123 uint32_t fileWriteLength_ = 0; 124 uint32_t mmapFileLength_ = 0; 125 uint32_t messageWriteOffset_ = 0; 126 size_t pageSize_ = 0; 127 size_t mapOffset_ = 0; 128 129 DISALLOW_COPY_AND_MOVE(TraceFileWriter); 130 }; 131 132 using TraceFileWriterPtr = STD_PTR(shared, TraceFileWriter); 133 134 #endif // !TRANCE_FILER_WRITER_H