Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Add ScopedTags. #217

Closed
wants to merge 1 commit into from
Closed
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
24 changes: 24 additions & 0 deletions opencensus/tags/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ cc_library(
],
)

cc_library(
name = "scoped_tags",
srcs = ["internal/scoped_tags.cc"],
hdrs = ["scoped_tags.h"],
copts = DEFAULT_COPTS,
visibility = ["//visibility:public"],
deps = [
":tags",
"//opencensus/context",
],
)

cc_library(
name = "with_tag_map",
srcs = ["internal/with_tag_map.cc"],
Expand Down Expand Up @@ -76,6 +88,18 @@ cc_test(
],
)

cc_test(
name = "scoped_tags_test",
srcs = ["internal/scoped_tags_test.cc"],
copts = TEST_COPTS,
deps = [
":scoped_tags",
":tags",
"//opencensus/context",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "with_tag_map_test",
srcs = ["internal/with_tag_map_test.cc"],
Expand Down
40 changes: 40 additions & 0 deletions opencensus/tags/internal/scoped_tags.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2018, OpenCensus Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "opencensus/tags/scoped_tags.h"

#include <initializer_list>
#include <utility>

#include "absl/strings/string_view.h"
#include "opencensus/tags/tag_key.h"

// Guard macro from scoped_tags.h.
#undef ScopedTags

namespace opencensus {
namespace tags {

ScopedTags::ScopedTags(
std::initializer_list<std::pair<TagKey, absl::string_view>> tags)
: swapped_tag_map_({}) {
// TODO: Implement this.
}

ScopedTags::~ScopedTags() {
// TODO: Implement this.
}

} // namespace tags
} // namespace opencensus
70 changes: 70 additions & 0 deletions opencensus/tags/internal/scoped_tags_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2018, OpenCensus Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "opencensus/tags/scoped_tags.h"

#include <iostream>

#include "gtest/gtest.h"
//#include "opencensus/context/context.h"
#include "opencensus/tags/tag_key.h"

// Not in namespace ::opencensus::context in order to better reflect what user
// code should look like.

namespace {

void ExpectNoTags() {
// Implement this.
}

TEST(ScopedTagsTest, NestedScopes) {
static const auto k1 = opencensus::tags::TagKey::Register("key1");
static const auto k2 = opencensus::tags::TagKey::Register("key2");
static const auto k3 = opencensus::tags::TagKey::Register("key3");

ExpectNoTags();
{
opencensus::tags::ScopedTags tags1({{k1, "v1"}});
// Expect something.
{
opencensus::tags::ScopedTags tags2({{k2, "v2"}, {k3, "v3"}});
// Expect something.
}
}
ExpectNoTags();
}

TEST(ScopedTagsTest, ReplaceValue) {
static const auto k1 = opencensus::tags::TagKey::Register("key1");
static const auto k2 = opencensus::tags::TagKey::Register("key2");
static const auto k3 = opencensus::tags::TagKey::Register("key3");

// Order shouldn't matter.
opencensus::tags::ScopedTags tags1({{k2, "v2"}, {k1, "v1"}});
{
opencensus::tags::ScopedTags tags2({{k3, "v3"}, {k2, "xx"}});
// Expect something.
}
}

// Disable non-compilation test.
#if 0
TEST(ScopedTagsTest, NCForgotName) {
static const auto k1 = opencensus::tags::TagKey::Register("key1");
opencensus::tags::ScopedTags({{k1, "v1"}});
}
#endif

} // namespace
58 changes: 58 additions & 0 deletions opencensus/tags/scoped_tags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2018, OpenCensus Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef OPENCENSUS_TAGS_SCOPED_TAGS_H_
#define OPENCENSUS_TAGS_SCOPED_TAGS_H_

#include <initializer_list>
#include <utility>

#include "absl/strings/string_view.h"
#include "opencensus/tags/tag_key.h"
#include "opencensus/tags/tag_map.h"

namespace opencensus {
namespace tags {

// ScopedTags is an RAII object, only ever stack-allocate it. While it's in
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is a RAII... While it is in

// scope, the current Context will execute with the specified tags added. If a
// tag key was already in use, its value will be replaced.
class ScopedTags {
public:
explicit ScopedTags(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at other languages:
https://github.com/census-instrumentation/opencensus-java/blob/master/api/src/main/java/io/opencensus/tags/TagContextBuilder.java
https://github.com/census-instrumentation/opencensus-go/blob/master/tag/map.go

It seems to me that we need some possible mutations:

  • upsert/put which adds if not exist + update if exists.
  • remove which removes a tag.

Should we support these operations? Should we also offer them to modify a TagMap (not in the context)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScopedTags does upsert.

We don't currently have a way to delete, and TagMap's API is pretty limited (I'm working on this)

std::initializer_list<std::pair<TagKey, absl::string_view>> tags);
~ScopedTags();

private:
ScopedTags() = delete;
ScopedTags(const ScopedTags&) = delete;
ScopedTags(ScopedTags&&) = delete;
ScopedTags& operator=(const ScopedTags&) = delete;
ScopedTags& operator=(ScopedTags&&) = delete;

TagMap swapped_tag_map_;
};

// Catch a bug where no name is given and the object is immediately discarded.
#define ScopedTags(x) \
do { \
static_assert( \
false, \
"ScopedTags needs to be an object on the stack and have a name"); \
} while (0)

} // namespace tags
} // namespace opencensus

#endif // OPENCENSUS_TAGS_SCOPED_TAGS_H_