Skip to content

Commit 8d36662

Browse files
committed
Add log message when a GET request starts and fails
This includes the request duration and enough information to trace between the begin and end of the request.
1 parent 053da60 commit 8d36662

File tree

4 files changed

+71
-29
lines changed

4 files changed

+71
-29
lines changed

src/S3Commands.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ bool AmazonS3SendMultipartPart::GetEtag(std::string &result) {
562562
AmazonS3Download::~AmazonS3Download() {}
563563

564564
bool AmazonS3Download::SendRequest(off_t offset, size_t size) {
565+
m_request_start = std::chrono::steady_clock::now();
565566
if (offset != 0 || size != 0) {
566567
std::string range;
567568
formatstr(range, "bytes=%lld-%lld", static_cast<long long int>(offset),

src/S3Commands.hh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ class AmazonS3Download : public AmazonRequest {
272272

273273
virtual bool SendRequest(off_t offset, size_t size);
274274

275+
// Return the elapsed time since the request was started with SendRequest().
276+
std::chrono::steady_clock::duration getElapsedTime() const {
277+
return std::chrono::steady_clock::now() - m_request_start;
278+
}
279+
275280
protected:
276281
virtual bool IsBlocking() { return true; }
277282
virtual std::string_view *requestResult() override {
@@ -280,6 +285,7 @@ class AmazonS3Download : public AmazonRequest {
280285

281286
private:
282287
char *m_buffer{nullptr};
288+
std::chrono::steady_clock::time_point m_request_start;
283289
std::string_view m_buffer_view;
284290
};
285291

src/S3File.cc

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ int S3File::Open(const char *path, int Oflag, mode_t Mode, XrdOucEnv &env) {
124124
}
125125

126126
ssize_t S3File::Read(void *buffer, off_t offset, size_t size) {
127-
return m_cache.Read(*this, static_cast<char *>(buffer), offset, size);
127+
return m_cache.Read(static_cast<char *>(buffer), offset, size);
128128
}
129129

130130
int S3File::Fstat(struct stat *buff) {
@@ -573,8 +573,8 @@ bool S3File::S3Cache::CouldUse(off_t req_off, size_t req_size,
573573
}
574574
}
575575

576-
void S3File::S3Cache::DownloadCaches(S3File &file, bool download_a,
577-
bool download_b, bool locked) {
576+
void S3File::S3Cache::DownloadCaches(bool download_a, bool download_b,
577+
bool locked) {
578578
if (!download_a && !download_b) {
579579
return;
580580
}
@@ -584,25 +584,25 @@ void S3File::S3Cache::DownloadCaches(S3File &file, bool download_a,
584584
lk.lock();
585585
}
586586
if (download_a) {
587-
m_a.Download(file);
587+
m_a.Download(m_parent);
588588
}
589589
if (download_b) {
590-
m_b.Download(file);
590+
m_b.Download(m_parent);
591591
}
592592
}
593593

594-
ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
595-
size_t size) {
596-
if (offset >= file.content_length) {
594+
ssize_t S3File::S3Cache::Read(char *buffer, off_t offset, size_t size) {
595+
if (offset >= m_parent.content_length) {
597596
return 0;
598597
}
599-
if (offset + static_cast<off_t>(size) > file.content_length) {
600-
size = file.content_length - offset;
598+
if (offset + static_cast<off_t>(size) > m_parent.content_length) {
599+
size = m_parent.content_length - offset;
601600
}
602-
if (file.m_log.getMsgMask() & LogMask::Debug) {
601+
if (m_parent.m_log.getMsgMask() & LogMask::Debug) {
603602
std::stringstream ss;
604-
ss << "Read request for offset=" << offset << ", size=" << size;
605-
file.m_log.Log(LogMask::Debug, "cache", ss.str().c_str());
603+
ss << "Read request for object=" << m_parent.m_object
604+
<< ", offset=" << offset << ", size=" << size;
605+
m_parent.m_log.Log(LogMask::Debug, "cache", ss.str().c_str());
606606
}
607607

608608
off_t req3_off, req4_off, req5_off, req6_off;
@@ -637,8 +637,8 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
637637
// download those bypassing the cache.
638638
bool downloaded;
639639
size_t bypass_size = req3_size;
640-
std::tie(req3_off, req3_size, downloaded) =
641-
file.DownloadBypass(req3_off, req3_size, buffer + req3_off - offset);
640+
std::tie(req3_off, req3_size, downloaded) = m_parent.DownloadBypass(
641+
req3_off, req3_size, buffer + req3_off - offset);
642642
if (req3_size < 0) {
643643
m_errors += 1;
644644
return -1;
@@ -648,8 +648,8 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
648648
m_bypass_count += 1;
649649
}
650650
bypass_size = req4_size;
651-
std::tie(req4_off, req4_size, downloaded) =
652-
file.DownloadBypass(req4_off, req4_size, buffer + req4_off - offset);
651+
std::tie(req4_off, req4_size, downloaded) = m_parent.DownloadBypass(
652+
req4_off, req4_size, buffer + req4_off - offset);
653653
if (req4_size < 0) {
654654
m_errors += 1;
655655
return -1;
@@ -659,8 +659,8 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
659659
m_bypass_count += 1;
660660
}
661661
bypass_size = req5_size;
662-
std::tie(req5_off, req5_size, downloaded) =
663-
file.DownloadBypass(req5_off, req5_size, buffer + req5_off - offset);
662+
std::tie(req5_off, req5_size, downloaded) = m_parent.DownloadBypass(
663+
req5_off, req5_size, buffer + req5_off - offset);
664664
if (req5_size < 0) {
665665
m_errors += 1;
666666
return -1;
@@ -670,8 +670,8 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
670670
m_bypass_count += 1;
671671
}
672672
bypass_size = req6_size;
673-
std::tie(req6_off, req6_size, downloaded) =
674-
file.DownloadBypass(req6_off, req6_size, buffer + req6_off - offset);
673+
std::tie(req6_off, req6_size, downloaded) = m_parent.DownloadBypass(
674+
req6_off, req6_size, buffer + req6_off - offset);
675675
if (req6_size < 0) {
676676
m_errors += 1;
677677
return -1;
@@ -690,7 +690,7 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
690690
std::unique_lock lk{m_mutex};
691691
auto next_offset = std::max(m_a.m_off, m_b.m_off) +
692692
static_cast<off_t>(m_cache_entry_size);
693-
if (next_offset < file.content_length) {
693+
if (next_offset < m_parent.content_length) {
694694
if (!m_a.m_inprogress && m_a.m_used >= m_cache_entry_size) {
695695
m_a.m_inprogress = true;
696696
m_a.m_off = next_offset;
@@ -712,7 +712,7 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
712712
m_prefetch_count++;
713713
m_prefetch_bytes += m_cache_entry_size;
714714
}
715-
DownloadCaches(file, download_a, download_b, false);
715+
DownloadCaches(download_a, download_b, false);
716716
return size;
717717
}
718718
// At this point, the only remaining data requests must be less than the
@@ -914,7 +914,7 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
914914
;
915915
download_a = true;
916916
m_a.m_inprogress = true;
917-
if (prefetch_offset < file.content_length) {
917+
if (prefetch_offset < m_parent.content_length) {
918918
m_b.m_off = prefetch_offset;
919919
prefetch_b = true;
920920
m_b.m_inprogress = true;
@@ -956,7 +956,7 @@ ssize_t S3File::S3Cache::Read(S3File &file, char *buffer, off_t offset,
956956
m_prefetch_count += 1;
957957
m_prefetch_bytes += m_cache_entry_size;
958958
}
959-
DownloadCaches(file, download_a, download_b || prefetch_b, true);
959+
DownloadCaches(download_a, download_b || prefetch_b, true);
960960
}
961961
return size;
962962
}
@@ -965,6 +965,29 @@ void S3File::S3Cache::Entry::Notify() {
965965
std::unique_lock lk(m_parent.m_mutex);
966966
m_inprogress = false;
967967
m_failed = !m_request->getErrorCode().empty();
968+
if ((m_parent.m_parent.m_log.getMsgMask() & LogMask::Warning) && m_failed) {
969+
std::stringstream ss;
970+
auto duration_ms =
971+
std::chrono::duration_cast<std::chrono::milliseconds>(
972+
m_request->getElapsedTime())
973+
.count();
974+
ss << "Finished GET for object=" << m_parent.m_parent.m_object
975+
<< ", offset=" << m_off << ", size=" << m_data.size()
976+
<< ", duration_ms=" << duration_ms << "; failed with error '"
977+
<< m_request->getErrorCode() << "'";
978+
m_parent.m_parent.m_log.Log(LogMask::Warning, "cache",
979+
ss.str().c_str());
980+
} else if (m_parent.m_parent.m_log.getMsgMask() & LogMask::Debug) {
981+
std::stringstream ss;
982+
auto duration_ms =
983+
std::chrono::duration_cast<std::chrono::milliseconds>(
984+
m_request->getElapsedTime())
985+
.count();
986+
ss << "Finished GET for object=" << m_parent.m_parent.m_object
987+
<< ", offset=" << m_off << ", size=" << m_data.size()
988+
<< ", duration_ms=" << duration_ms << "; succeeded";
989+
m_parent.m_parent.m_log.Log(LogMask::Debug, "cache", ss.str().c_str());
990+
}
968991
m_request = nullptr;
969992

970993
m_parent.m_cv.notify_all();
@@ -986,6 +1009,14 @@ void S3File::S3Cache::Entry::Download(S3File &file) {
9861009
// otherwise deadlock may occur.
9871010
auto off = m_off;
9881011
m_parent.m_mutex.unlock();
1012+
1013+
if (file.m_log.getMsgMask() & LogMask::Debug) {
1014+
std::stringstream ss;
1015+
ss << "Issuing GET for object=" << file.m_object << ", offset=" << m_off
1016+
<< ", size=" << request_size;
1017+
file.m_log.Log(LogMask::Debug, "cache", ss.str().c_str());
1018+
}
1019+
9891020
if (!m_request->SendRequest(off, m_cache_entry_size)) {
9901021
m_parent.m_mutex.lock();
9911022
std::stringstream ss;

src/S3File.hh

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ class S3File : public XrdOssDF {
273273
std::condition_variable m_cv; // Condition variable for notifying that
274274
// new downloaded data is available.
275275

276+
S3File
277+
&m_parent; // Reference to the S3File object that owns this cache.
278+
276279
// Returns `true` if the request offset would be inside the cache entry.
277280
// The request offset is assumed to be aligned to be inside a single
278281
// cache entry (that is, smaller than a cache entry and not spanning two
@@ -286,15 +289,16 @@ class S3File : public XrdOssDF {
286289
// Trigger the non-blocking download into the cache entries.
287290
// The condition variable will be notified when one of the caches
288291
// finishes.
289-
void DownloadCaches(S3File &file, bool download_a, bool download_b,
290-
bool locked);
292+
void DownloadCaches(bool download_a, bool download_b, bool locked);
291293

292294
// Trigger a blocking read from a given file
293-
ssize_t Read(S3File &file, char *buffer, off_t offset, size_t size);
295+
ssize_t Read(char *buffer, off_t offset, size_t size);
296+
297+
S3Cache(S3File &file) : m_parent(file) {}
294298

295299
// Shutdown the cache; ensure all reads are completed before
296300
// deleting the objects.
297301
~S3Cache();
298302
};
299-
S3Cache m_cache;
303+
S3Cache m_cache{*this};
300304
};

0 commit comments

Comments
 (0)