Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tensorflow_serving/util/prometheus_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ namespace serving {
namespace {

string SanitizeLabelValue(const string& value) {
// Backslash and double quote have to be escaped.
// Backslash, double quote and line feed have to be escaped.
string new_value = value;
// Replace \ with \\.
RE2::GlobalReplace(&new_value, "\\\\", "\\\\\\\\");
// Replace " with \".
RE2::GlobalReplace(&new_value, "\"", "\\\\\"");
// Replace a line feed with \n.
RE2::GlobalReplace(&new_value, "\n", "\\\\n");
return new_value;
}

Expand Down
18 changes: 18 additions & 0 deletions tensorflow_serving/util/prometheus_exporter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ TEST(PrometheusExporterTest, SanitizeLabelValue) {
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
}

TEST(PrometheusExporterTest, SanitizeLabelValueLineFeed) {
auto exporter = absl::make_unique<PrometheusExporter>();
auto counter = absl::WrapUnique(
monitoring::Counter<1>::New("/test/path/total", "A counter.", "name"));
// label value: abc<LF>def
counter->GetCell("abc\ndef")->IncrementBy(2);

string http_page;
Status status = exporter->GeneratePage(&http_page);

string expected_result =
absl::StrJoin({"# TYPE :test:path:total counter",
":test:path:total{name=\"abc\\ndef\"} 2"},
"\n");
absl::StrAppend(&expected_result, "\n");
EXPECT_PRED_FORMAT2(testing::IsSubstring, expected_result, http_page);
}

TEST(PrometheusExporterTest, SanitizeLabelName) {
auto exporter = absl::make_unique<PrometheusExporter>();
auto counter = absl::WrapUnique(monitoring::Counter<1>::New(
Expand Down
Loading