rotating_file.cpp 2.4 KB

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