Fix copyright lines
[folly.git] / folly / experimental / logging / xlog.cpp
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <folly/experimental/logging/xlog.h>
17 #include <folly/Synchronized.h>
18
19 using folly::StringPiece;
20
21 namespace folly {
22
23 namespace {
24 /**
25  * buck copies header files from their original location in the source tree
26  * and places them under buck-out/ with a path like
27  * buck-out/<rule-name-components>/<original-path>
28  *
29  * We want to strip off the buck-out/<rule-name-components> portion,
30  * so that the filename we use is just the original path in the source tree.
31  *
32  * The <rule-name-component> section should always end in a path component that
33  * includes a '#': it's format is <rule-name>#<parameters>, where <parameters>
34  * is a comma separated list that never includes '/'.
35  *
36  * Search for the first path component with a '#', and strip off everything up
37  * to this component.
38  */
39 StringPiece stripBuckOutPrefix(StringPiece filename) {
40   size_t idx = 0;
41   while (true) {
42     auto end = filename.find('/', idx);
43     if (end == StringPiece::npos) {
44       // We were unable to find where the buck-out prefix should end.
45       return filename;
46     }
47
48     auto component = filename.subpiece(idx, end - idx);
49     if (component.find('#') != StringPiece::npos) {
50       return filename.subpiece(end + 1);
51     }
52     idx = end + 1;
53   }
54 }
55 } // namespace
56
57 std::string getXlogCategoryNameForFile(StringPiece filename) {
58   // Buck mangles the directory layout for header files.  Rather than including
59   // them from their original location, it moves them into deep directories
60   // inside buck-out, and includes them from there.
61   //
62   // If this path looks like a buck header directory, try to strip off the
63   // buck-specific portion.
64   if (filename.startsWith("buck-out/")) {
65     filename = stripBuckOutPrefix(filename);
66   }
67
68   std::string categoryName = filename.str();
69
70   // Translate slashes to dots, to turn the directory layout into
71   // a category hierarchy.
72   for (size_t n = 0; n < categoryName.size(); ++n) {
73     if (categoryName[n] == '/') {
74       categoryName[n] = '.';
75     }
76   }
77
78   return categoryName;
79 }
80
81 template <bool IsInHeaderFile>
82 LogLevel XlogLevelInfo<IsInHeaderFile>::loadLevelFull(
83     folly::StringPiece categoryName,
84     bool isOverridden) {
85   auto currentLevel = level_.load(std::memory_order_acquire);
86   if (UNLIKELY(currentLevel == ::folly::LogLevel::UNINITIALIZED)) {
87     return LoggerDB::get()->xlogInit(
88         isOverridden ? categoryName : getXlogCategoryNameForFile(categoryName),
89         &level_,
90         nullptr);
91   }
92   return currentLevel;
93 }
94
95 template <bool IsInHeaderFile>
96 LogCategory* XlogCategoryInfo<IsInHeaderFile>::init(
97     folly::StringPiece categoryName,
98     bool isOverridden) {
99   return LoggerDB::get()->xlogInitCategory(
100       isOverridden ? categoryName : getXlogCategoryNameForFile(categoryName),
101       &category_,
102       &isInitialized_);
103 }
104
105 #ifdef __INCLUDE_LEVEL__
106 LogLevel XlogLevelInfo<false>::loadLevelFull(
107     folly::StringPiece categoryName,
108     bool isOverridden,
109     XlogFileScopeInfo* fileScopeInfo) {
110   auto currentLevel = fileScopeInfo->level.load(std::memory_order_acquire);
111   if (UNLIKELY(currentLevel == ::folly::LogLevel::UNINITIALIZED)) {
112     return LoggerDB::get()->xlogInit(
113         isOverridden ? categoryName : getXlogCategoryNameForFile(categoryName),
114         &fileScopeInfo->level,
115         &fileScopeInfo->category);
116   }
117   return currentLevel;
118 }
119 #endif
120
121 // Explicitly instantiations of XlogLevelInfo and XlogCategoryInfo
122 // If __INCLUDE_LEVEL__ is not available only the "true" variants ever get
123 // used, because we cannot determine if we are ever in the .cpp file being
124 // compiled or not.
125 template class XlogLevelInfo<true>;
126 template class XlogCategoryInfo<true>;
127 } // namespace folly