rotating_file.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #include "rotating_file.h"
  2. #include "file.h"
  3. #include "record.h"
  4. #include <util/string/builder.h>
  5. #include <util/system/fstat.h>
  6. #include <util/system/rwlock.h>
  7. #include <util/system/fs.h>
  8. #include <library/cpp/deprecated/atomic/atomic.h>
  9. /*
  10. * rotating file log
  11. * if Size_ > MaxSizeBytes
  12. * Path.(N-1) -> Path.N
  13. * Path.(N-2) -> Path.(N-1)
  14. * ...
  15. * Path.1 -> Path.2
  16. * Path -> Path.1
  17. */
  18. class TRotatingFileLogBackend::TImpl {
  19. public:
  20. inline TImpl(const TString& path, const ui64 maxSizeBytes, const ui32 rotatedFilesCount)
  21. : Log_(path)
  22. , Path_(path)
  23. , MaxSizeBytes_(maxSizeBytes)
  24. , Size_(TFileStat(Path_).Size)
  25. , RotatedFilesCount_(rotatedFilesCount)
  26. {
  27. Y_ENSURE(RotatedFilesCount_ != 0);
  28. }
  29. inline void WriteData(const TLogRecord& rec) {
  30. if (static_cast<ui64>(AtomicGet(Size_)) > MaxSizeBytes_) {
  31. TWriteGuard guard(Lock_);
  32. if (static_cast<ui64>(AtomicGet(Size_)) > MaxSizeBytes_) {
  33. TString newLogPath(TStringBuilder{} << Path_ << "." << RotatedFilesCount_);
  34. for (size_t fileId = RotatedFilesCount_ - 1; fileId; --fileId) {
  35. TString oldLogPath(TStringBuilder{} << Path_ << "." << fileId);
  36. NFs::Rename(oldLogPath, newLogPath);
  37. newLogPath = oldLogPath;
  38. }
  39. NFs::Rename(Path_, newLogPath);
  40. Log_.ReopenLog();
  41. AtomicSet(Size_, 0);
  42. }
  43. }
  44. TReadGuard guard(Lock_);
  45. Log_.WriteData(rec);
  46. AtomicAdd(Size_, rec.Len);
  47. }
  48. inline void ReopenLog() {
  49. TWriteGuard guard(Lock_);
  50. Log_.ReopenLog();
  51. AtomicSet(Size_, TFileStat(Path_).Size);
  52. }
  53. private:
  54. TRWMutex Lock_;
  55. TFileLogBackend Log_;
  56. const TString Path_;
  57. const ui64 MaxSizeBytes_;
  58. TAtomic Size_;
  59. const ui32 RotatedFilesCount_;
  60. };
  61. TRotatingFileLogBackend::TRotatingFileLogBackend(const TString& path, const ui64 maxSizeByte, const ui32 rotatedFilesCount)
  62. : Impl_(new TImpl(path, maxSizeByte, rotatedFilesCount))
  63. {
  64. }
  65. TRotatingFileLogBackend::~TRotatingFileLogBackend() {
  66. }
  67. void TRotatingFileLogBackend::WriteData(const TLogRecord& rec) {
  68. Impl_->WriteData(rec);
  69. }
  70. void TRotatingFileLogBackend::ReopenLog() {
  71. TAtomicSharedPtr<TImpl> copy = Impl_;
  72. if (copy) {
  73. copy->ReopenLog();
  74. }
  75. }