/* * Copyright 2015 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
bool IsFile(absl::string_view file) { struct stat st; int res = ::stat(std::string(file).c_str(), &st); // Treat symlinks, named pipes, etc. all as files. return res == 0 && !S_ISDIR(st.st_mode);
}
bool IsFolder(absl::string_view file) { struct stat st; int res = ::stat(std::string(file).c_str(), &st); return res == 0 && S_ISDIR(st.st_mode);
}
std::optional<size_t> GetFileSize(absl::string_view file) { struct stat st; if (::stat(std::string(file).c_str(), &st) != 0) return std::nullopt; return st.st_size;
}
bool FileRotatingStream::Write(constvoid* data, size_t data_len) { if (!file_.is_open()) {
std::fprintf(stderr, "Open() must be called before Write.\n"); returnfalse;
} while (data_len > 0) { // Write as much as will fit in to the current file.
RTC_DCHECK_LT(current_bytes_written_, max_file_size_);
size_t remaining_bytes = max_file_size_ - current_bytes_written_;
size_t write_length = std::min(data_len, remaining_bytes);
if (!file_.Write(data, write_length)) { returnfalse;
} if (disable_buffering_ && !file_.Flush()) { returnfalse;
}
current_bytes_written_ += write_length;
// If we're done with this file, rotate it out. if (current_bytes_written_ >= max_file_size_) {
RTC_DCHECK_EQ(current_bytes_written_, max_file_size_);
RotateFiles();
}
data_len -= write_length;
data = static_cast<constvoid*>(static_cast<constchar*>(data) + write_length);
} returntrue;
}
// Opens the appropriate file in the appropriate mode.
RTC_DCHECK_LT(current_file_index_, file_names_.size());
std::string file_path = file_names_[current_file_index_];
// We should always be writing to the zero-th file.
RTC_DCHECK_EQ(current_file_index_, 0); int error;
file_ = webrtc::FileWrapper::OpenWriteOnly(file_path, &error); if (!file_.is_open()) {
std::fprintf(stderr, "Failed to open: %s Error: %d\n", file_path.c_str(),
error); returnfalse;
} returntrue;
}
void FileRotatingStream::RotateFiles() {
CloseCurrentFile(); // Rotates the files by deleting the file at `rotation_index_`, which is the // oldest file and then renaming the newer files to have an incremented index. // See header file comments for example.
RTC_DCHECK_LT(rotation_index_, file_names_.size());
std::string file_to_delete = file_names_[rotation_index_]; if (IsFile(file_to_delete)) { if (!DeleteFile(file_to_delete)) {
std::fprintf(stderr, "Failed to delete: %s\n", file_to_delete.c_str());
}
} for (auto i = rotation_index_; i > 0; --i) {
std::string rotated_name = file_names_[i];
std::string unrotated_name = file_names_[i - 1]; if (IsFile(unrotated_name)) { if (!MoveFile(unrotated_name, rotated_name)) {
std::fprintf(stderr, "Failed to move: %s to %s\n",
unrotated_name.c_str(), rotated_name.c_str());
}
}
} // Create a new file for 0th index.
OpenCurrentFile();
OnRotation();
}
const size_t buffer_size = 32; char file_postfix[buffer_size]; // We want to zero pad the index so that it will sort nicely. constint max_digits = std::snprintf(nullptr, 0, "%zu", num_files - 1);
RTC_DCHECK_LT(1 + max_digits, buffer_size);
std::snprintf(file_postfix, buffer_size, "_%0*zu", max_digits, index);
void CallSessionFileRotatingStream::OnRotation() {
++num_rotations_; if (num_rotations_ == 1) { // On the first rotation adjust the max file size so subsequent files after // the first are smaller.
SetMaxFileSize(GetRotatingLogSize(max_total_log_size_));
} elseif (num_rotations_ == (GetNumFiles() - 1)) { // On the next rotation the very first file is going to be deleted. Change // the rotation index so this doesn't happen.
SetRotationIndex(GetRotationIndex() - 1);
}
}
// Plain sort of the file names would sort by age, i.e., oldest last. Using // std::greater gives us the desired chronological older, oldest first.
absl::c_sort(file_names_, std::greater<std::string>());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.