]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/port/win/win_logger.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
10 // Logger implementation that can be shared by all environments
11 // where enough posix functionality is available.
13 #include "port/win/win_logger.h"
14 #include "port/win/io_win.h"
22 #include "rocksdb/env.h"
24 #include "monitoring/iostats_context_imp.h"
25 #include "port/sys_time.h"
31 WinLogger::WinLogger(uint64_t (*gettid
)(), Env
* env
, HANDLE file
,
32 const InfoLogLevel log_level
)
37 last_flush_micros_(0),
39 flush_pending_(false) {}
41 void WinLogger::DebugWriter(const char* str
, int len
) {
42 DWORD bytesWritten
= 0;
43 BOOL ret
= WriteFile(file_
, str
, len
, &bytesWritten
, NULL
);
45 std::string errSz
= GetWindowsErrSz(GetLastError());
46 fprintf(stderr
, errSz
.c_str());
50 WinLogger::~WinLogger() { close(); }
52 void WinLogger::close() { CloseHandle(file_
); }
54 void WinLogger::Flush() {
56 flush_pending_
= false;
57 // With Windows API writes go to OS buffers directly so no fflush needed
58 // unlike with C runtime API. We don't flush all the way to disk
62 last_flush_micros_
= env_
->NowMicros();
65 void WinLogger::Logv(const char* format
, va_list ap
) {
66 IOSTATS_TIMER_GUARD(logger_nanos
);
68 const uint64_t thread_id
= (*gettid_
)();
70 // We try twice: the first time with a fixed-size stack allocated buffer,
71 // and the second time with a much larger dynamically allocated buffer.
73 std::unique_ptr
<char[]> largeBuffer
;
74 for (int iter
= 0; iter
< 2; ++iter
) {
78 bufsize
= sizeof(buffer
);
82 largeBuffer
.reset(new char[bufsize
]);
83 base
= largeBuffer
.get();
87 char* limit
= base
+ bufsize
;
89 struct timeval now_tv
;
90 gettimeofday(&now_tv
, nullptr);
91 const time_t seconds
= now_tv
.tv_sec
;
93 localtime_s(&t
, &seconds
);
94 p
+= snprintf(p
, limit
- p
, "%04d/%02d/%02d-%02d:%02d:%02d.%06d %llx ",
95 t
.tm_year
+ 1900, t
.tm_mon
+ 1, t
.tm_mday
, t
.tm_hour
,
96 t
.tm_min
, t
.tm_sec
, static_cast<int>(now_tv
.tv_usec
),
97 static_cast<long long unsigned int>(thread_id
));
102 va_copy(backup_ap
, ap
);
103 int done
= vsnprintf(p
, limit
- p
, format
, backup_ap
);
112 // Truncate to available space if necessary
115 continue; // Try again with larger buffer
121 // Add newline if necessary
122 if (p
== base
|| p
[-1] != '\n') {
127 const size_t write_size
= p
- base
;
129 DWORD bytesWritten
= 0;
130 BOOL ret
= WriteFile(file_
, base
, static_cast<DWORD
>(write_size
),
131 &bytesWritten
, NULL
);
133 std::string errSz
= GetWindowsErrSz(GetLastError());
134 fprintf(stderr
, errSz
.c_str());
137 flush_pending_
= true;
138 assert((bytesWritten
== write_size
) || (ret
== FALSE
));
139 if (bytesWritten
> 0) {
140 log_size_
+= write_size
;
143 uint64_t now_micros
=
144 static_cast<uint64_t>(now_tv
.tv_sec
) * 1000000 + now_tv
.tv_usec
;
145 if (now_micros
- last_flush_micros_
>= flush_every_seconds_
* 1000000) {
146 flush_pending_
= false;
147 // With Windows API writes go to OS buffers directly so no fflush needed
148 // unlike with C runtime API. We don't flush all the way to disk
150 last_flush_micros_
= now_micros
;
156 size_t WinLogger::GetLogFileSize() const { return log_size_
; }
160 } // namespace rocksdb