mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
edenapi: log unfetchable blobs and trees with EdenAPI
Summary: Add EdenAPI fallover scuba logging to `HgBackingStore`. The reason that this is being added to `HgBackingStore` instead of `HgQueuedBackingStore` is that we don't have good access to the actual point where trees and blobs are imported from HgImporter in there. As a result we have to get StructuredLogger in there and send events directly from there. Reviewed By: xavierd Differential Revision: D34217906 fbshipit-source-id: 795b61ef6a2ea52e8b67cd08633ec017e5bdbb06
This commit is contained in:
parent
5bc49f102d
commit
3c6f866635
@ -1830,7 +1830,8 @@ shared_ptr<BackingStore> EdenServer::createBackingStore(
|
||||
serverState_->getThreadPool().get(),
|
||||
reloadableConfig,
|
||||
getSharedStats(),
|
||||
metadataImporterFactory_);
|
||||
metadataImporterFactory_,
|
||||
serverState_->getStructuredLogger());
|
||||
return std::make_shared<LocalStoreCachedBackingStore>(
|
||||
make_shared<HgQueuedBackingStore>(
|
||||
localStore_,
|
||||
|
@ -39,7 +39,9 @@
|
||||
#include "eden/fs/store/hg/HgProxyHash.h"
|
||||
#include "eden/fs/store/hg/MetadataImporter.h"
|
||||
#include "eden/fs/telemetry/EdenStats.h"
|
||||
#include "eden/fs/telemetry/LogEvent.h"
|
||||
#include "eden/fs/telemetry/RequestMetricsScope.h"
|
||||
#include "eden/fs/telemetry/StructuredLogger.h"
|
||||
#include "eden/fs/utils/Bug.h"
|
||||
#include "eden/fs/utils/EnumValue.h"
|
||||
#include "eden/fs/utils/UnboundedQueueExecutor.h"
|
||||
@ -152,7 +154,8 @@ HgBackingStore::HgBackingStore(
|
||||
UnboundedQueueExecutor* serverThreadPool,
|
||||
std::shared_ptr<ReloadableConfig> config,
|
||||
std::shared_ptr<EdenStats> stats,
|
||||
MetadataImporterFactory metadataImporterFactory)
|
||||
MetadataImporterFactory metadataImporterFactory,
|
||||
std::shared_ptr<StructuredLogger> logger)
|
||||
: localStore_(std::move(localStore)),
|
||||
stats_(stats),
|
||||
importThreadPool_(make_unique<folly::CPUThreadPoolExecutor>(
|
||||
@ -174,11 +177,13 @@ HgBackingStore::HgBackingStore(
|
||||
std::make_shared<HgImporterThreadFactory>(repository, stats))),
|
||||
config_(config),
|
||||
serverThreadPool_(serverThreadPool),
|
||||
useEdenApi_(config->getEdenConfig()->useEdenApi.getValue()),
|
||||
datapackStore_(
|
||||
repository,
|
||||
config->getEdenConfig()->useEdenApi.getValue(),
|
||||
useEdenApi_,
|
||||
config->getEdenConfig()->useAuxMetadata.getValue(),
|
||||
config) {
|
||||
config),
|
||||
logger_(logger) {
|
||||
HgImporter importer(repository, stats);
|
||||
const auto& options = importer.getOptions();
|
||||
repoName_ = options.repoName;
|
||||
@ -217,7 +222,9 @@ HgBackingStore::HgBackingStore(
|
||||
importThreadPool_{std::make_unique<HgImporterTestExecutor>(importer)},
|
||||
config_(std::move(config)),
|
||||
serverThreadPool_{importThreadPool_.get()},
|
||||
datapackStore_(repository, false, false, config_) {
|
||||
useEdenApi_{false},
|
||||
datapackStore_(repository, false, false, config_),
|
||||
logger_(nullptr) {
|
||||
const auto& options = importer->getOptions();
|
||||
repoName_ = options.repoName;
|
||||
metadataImporter_ = metadataImporterFactory(config_, repoName_, localStore_);
|
||||
@ -431,14 +438,22 @@ folly::Future<std::unique_ptr<Tree>> HgBackingStore::fetchTreeFromImporter(
|
||||
auto fut =
|
||||
folly::via(
|
||||
importThreadPool_.get(),
|
||||
[path,
|
||||
[this,
|
||||
path,
|
||||
manifestNode,
|
||||
stats = stats_,
|
||||
&liveImportTreeWatches = liveImportTreeWatches_] {
|
||||
Importer& importer = getThreadLocalImporter();
|
||||
folly::stop_watch<std::chrono::milliseconds> watch;
|
||||
RequestMetricsScope queueTracker{&liveImportTreeWatches};
|
||||
|
||||
if (useEdenApi_ && logger_) {
|
||||
logger_->logEvent(EdenApiMiss{
|
||||
repoName_,
|
||||
EdenApiMiss::Tree,
|
||||
path.stringPiece().toString(),
|
||||
manifestNode.toString(),
|
||||
});
|
||||
}
|
||||
auto serializedTree = importer.fetchTree(path, manifestNode);
|
||||
stats->getHgBackingStoreStatsForCurrentThread()
|
||||
.hgBackingStoreImportTree.addValue(watch.elapsed().count());
|
||||
@ -699,12 +714,21 @@ SemiFuture<std::unique_ptr<Blob>> HgBackingStore::fetchBlobFromHgImporter(
|
||||
HgProxyHash hgInfo) {
|
||||
return folly::via(
|
||||
importThreadPool_.get(),
|
||||
[stats = stats_,
|
||||
[this,
|
||||
stats = stats_,
|
||||
hgInfo = std::move(hgInfo),
|
||||
&liveImportBlobWatches = liveImportBlobWatches_] {
|
||||
Importer& importer = getThreadLocalImporter();
|
||||
folly::stop_watch<std::chrono::milliseconds> watch;
|
||||
RequestMetricsScope queueTracker{&liveImportBlobWatches};
|
||||
if (useEdenApi_ && logger_) {
|
||||
logger_->logEvent(EdenApiMiss{
|
||||
repoName_,
|
||||
EdenApiMiss::Blob,
|
||||
hgInfo.path().stringPiece().toString(),
|
||||
hgInfo.revHash().toString(),
|
||||
});
|
||||
}
|
||||
auto blob =
|
||||
importer.importFileContents(hgInfo.path(), hgInfo.revHash());
|
||||
stats->getHgBackingStoreStatsForCurrentThread()
|
||||
|
@ -32,6 +32,7 @@ class LocalStore;
|
||||
class UnboundedQueueExecutor;
|
||||
class ReloadableConfig;
|
||||
class HgProxyHash;
|
||||
class StructuredLogger;
|
||||
|
||||
/**
|
||||
* An implementation class for HgQueuedBackingStore that loads data out of a
|
||||
@ -48,7 +49,8 @@ class HgBackingStore {
|
||||
UnboundedQueueExecutor* serverThreadPool,
|
||||
std::shared_ptr<ReloadableConfig> config,
|
||||
std::shared_ptr<EdenStats> edenStats,
|
||||
MetadataImporterFactory metadataImporter);
|
||||
MetadataImporterFactory metadataImporter,
|
||||
std::shared_ptr<StructuredLogger> logger);
|
||||
|
||||
/**
|
||||
* Create an HgBackingStore suitable for use in unit tests. It uses an inline
|
||||
@ -201,9 +203,11 @@ class HgBackingStore {
|
||||
folly::Executor* serverThreadPool_;
|
||||
|
||||
std::string repoName_;
|
||||
const bool useEdenApi_;
|
||||
HgDatapackStore datapackStore_;
|
||||
|
||||
std::unique_ptr<MetadataImporter> metadataImporter_;
|
||||
std::shared_ptr<StructuredLogger> logger_;
|
||||
|
||||
// Track metrics for imports currently fetching data from hg
|
||||
mutable RequestMetricsScope::LockedRequestWatchList liveImportBlobWatches_;
|
||||
|
@ -244,5 +244,30 @@ struct ServerDataFetch {
|
||||
}
|
||||
};
|
||||
|
||||
struct EdenApiMiss {
|
||||
enum MissType : bool {
|
||||
Blob = 0,
|
||||
Tree = 1,
|
||||
};
|
||||
|
||||
static constexpr const char* type = "edenapi_miss";
|
||||
|
||||
std::string repo_name;
|
||||
MissType miss_type;
|
||||
std::string path;
|
||||
std::string hash;
|
||||
|
||||
void populate(DynamicEvent& event) const {
|
||||
event.addString("repo_source", repo_name);
|
||||
if (miss_type == Blob) {
|
||||
event.addString("edenapi_miss_type", "blob");
|
||||
} else {
|
||||
event.addString("edenapi_miss_type", "tree");
|
||||
}
|
||||
event.addString("path", path);
|
||||
event.addString("hash", hash);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace eden
|
||||
} // namespace facebook
|
||||
|
Loading…
Reference in New Issue
Block a user