| /** |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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. |
| */ |
| |
| /** |
| * @warning log rolling doesn't work correctly in 3.2.x, see: |
| * https://issues.apache.org/jira/browse/TS-1813, Apply the patch in |
| * TS-1813 to correct log rolling in 3.2.x |
| */ |
| |
| #include "tscpp/api/GlobalPlugin.h" |
| #include "tscpp/api/TransactionPlugin.h" |
| #include "tscpp/api/Logger.h" |
| #include "tscpp/api/PluginInit.h" |
| #include <cstring> |
| |
| using namespace atscppapi; |
| using std::string; |
| |
| namespace |
| { |
| Logger logger; |
| GlobalPlugin *plugin; |
| } // namespace |
| |
| /* |
| * You should always take advantage of the LOG_DEBUG, LOG_INFO, and LOG_ERROR |
| * macros available in Logger.h, they are easy to use as you can see below |
| * and will provide detailed information about the logging site such as |
| * filename, function name, and line number of the message |
| */ |
| |
| class GlobalHookPlugin : public GlobalPlugin |
| { |
| public: |
| GlobalHookPlugin() |
| { |
| memset(big_buffer_6kb_, 'a', sizeof(big_buffer_6kb_)); |
| big_buffer_6kb_[sizeof(big_buffer_6kb_) - 1] = '\0'; |
| |
| memset(big_buffer_14kb_, 'a', sizeof(big_buffer_14kb_)); |
| big_buffer_14kb_[sizeof(big_buffer_14kb_) - 1] = '\0'; |
| |
| registerHook(HOOK_READ_REQUEST_HEADERS_POST_REMAP); |
| } |
| |
| void |
| handleReadRequestHeadersPostRemap(Transaction &transaction) override |
| { |
| LOG_DEBUG(logger, |
| "handleReadRequestHeadersPostRemap.\n" |
| "\tRequest URL: %s\n" |
| "\tRequest Path: %s\n" |
| "\tRequest Query: %s\n" |
| "\tRequest Method: %s", |
| transaction.getClientRequest().getUrl().getUrlString().c_str(), |
| transaction.getClientRequest().getUrl().getPath().c_str(), transaction.getClientRequest().getUrl().getQuery().c_str(), |
| HTTP_METHOD_STRINGS[transaction.getClientRequest().getMethod()].c_str()); |
| |
| // Next, to demonstrate how you can change logging levels: |
| if (transaction.getClientRequest().getUrl().getPath() == "change_log_level") { |
| if (transaction.getClientRequest().getUrl().getQuery().find("level=debug") != string::npos) { |
| logger.setLogLevel(Logger::LOG_LEVEL_DEBUG); |
| LOG_DEBUG(logger, "Changed log level to DEBUG"); |
| } else if (transaction.getClientRequest().getUrl().getQuery().find("level=info") != string::npos) { |
| logger.setLogLevel(Logger::LOG_LEVEL_INFO); |
| LOG_INFO(logger, "Changed log level to INFO"); |
| } else if (transaction.getClientRequest().getUrl().getQuery().find("level=error") != string::npos) { |
| logger.setLogLevel(Logger::LOG_LEVEL_ERROR); |
| LOG_ERROR(logger, "Changed log level to ERROR"); |
| } |
| } |
| |
| // One drawback to using the Traffic Server Text Loggers is that you're limited in the size of the log |
| // lines, this limit is now set at 8kb for atscppapi, but this limit might be removed in the future. |
| LOG_INFO(logger, "This message will be dropped (see error.log) because it's just too big: %s", big_buffer_14kb_); |
| |
| // This should work though: |
| LOG_INFO(logger, "%s", big_buffer_6kb_); |
| |
| transaction.resume(); |
| } |
| |
| private: |
| char big_buffer_6kb_[6 * 1024]; |
| char big_buffer_14kb_[14 * 1024]; |
| }; |
| |
| void |
| TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED) |
| { |
| if (!RegisterGlobalPlugin("CPP_Example_Logger", "apache", "dev@trafficserver.apache.org")) { |
| return; |
| } |
| // Create a new logger |
| // This will create a log file with the name logger_example.log (since we left off |
| // the extension it will automatically add .log) |
| // |
| // The second argument is timestamp, which will force a timestamp on every log message |
| // this is enabled by default. |
| // The third argument is renaming enabled, which means if a log already exists with that |
| // name it will try logger_example.1 and so on, this is enabled by default. |
| // The fourth argument is the initial logging level this can always be changed with log.setLogLevel(). |
| // the default log level is LOG_LEVEL_INFO. |
| // The fifth argument is to enable log rolling, this is enabled by default. |
| // The sixth argument is the frequency in which we will roll the logs, 300 seconds is very low, |
| // the default for this argument is 3600. |
| logger.init("logger_example", true, true, Logger::LOG_LEVEL_DEBUG, true, 300); |
| |
| // Now that we've initialized a logger we can do all kinds of fun things on it: |
| logger.setRollingEnabled(true); // already done via log.init, just an example. |
| logger.setRollingIntervalSeconds(300); // already done via log.init |
| |
| // You have two ways to log to a logger, you can log directly on the object itself: |
| logger.logInfo("Hello World from: %s", argv[0]); |
| |
| // Alternatively you can take advantage of the super helper macros for logging |
| // that will include the file, function, and line number automatically as part |
| // of the log message: |
| LOG_INFO(logger, "Hello World with more info from: %s", argv[0]); |
| |
| // This will hurt performance, but it's an option that's always available to you |
| // to force flush the logs. Otherwise TrafficServer will flush the logs around |
| // once every second. You should really avoid flushing the log unless it's really necessary. |
| logger.flush(); |
| |
| plugin = new GlobalHookPlugin(); |
| } |