diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2023-03-01 16:04:10 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2023-03-01 16:04:10 +0000 |
commit | 9298ba38f3f62ec7f6a27403fa663f31f366a604 (patch) | |
tree | 5c7457a24ed430d1b31938d57f6c35992a3f8d76 /vespalog | |
parent | f66e4be5877a7e5556511ccfe9ecc5ecab4d5366 (diff) |
Reduce transitive includes.
Diffstat (limited to 'vespalog')
-rw-r--r-- | vespalog/src/logctl/logctl.cpp | 3 | ||||
-rw-r--r-- | vespalog/src/logger/llreader.cpp | 11 | ||||
-rw-r--r-- | vespalog/src/test/bufferedlogskiptest.cpp | 9 | ||||
-rw-r--r-- | vespalog/src/test/bufferedlogtest.cpp | 21 | ||||
-rw-r--r-- | vespalog/src/test/threads/testthreads.cpp | 1 | ||||
-rw-r--r-- | vespalog/src/vespa/log/bufferedlogger.cpp | 43 | ||||
-rw-r--r-- | vespalog/src/vespa/log/bufferedlogger.h | 11 | ||||
-rw-r--r-- | vespalog/src/vespa/log/component.cpp | 1 | ||||
-rw-r--r-- | vespalog/src/vespa/log/internal.h | 21 | ||||
-rw-r--r-- | vespalog/src/vespa/log/llparser.cpp | 1 | ||||
-rw-r--r-- | vespalog/src/vespa/log/log-target-file.cpp | 10 | ||||
-rw-r--r-- | vespalog/src/vespa/log/log.cpp | 38 | ||||
-rw-r--r-- | vespalog/src/vespa/log/log.h | 44 |
13 files changed, 102 insertions, 112 deletions
diff --git a/vespalog/src/logctl/logctl.cpp b/vespalog/src/logctl/logctl.cpp index 4cf44e9cd22..9a8987fc462 100644 --- a/vespalog/src/logctl/logctl.cpp +++ b/vespalog/src/logctl/logctl.cpp @@ -6,6 +6,7 @@ #include <vespa/log/component.h> #include <optional> +#include <cstring> #include <unistd.h> #include <dirent.h> #include <sys/stat.h> @@ -16,7 +17,7 @@ LOG_SETUP("vespa-logctl"); using namespace ns_log; static void modifyLevels(const char *file, const char *component, const char *levels, - bool shouldCreateFile, bool shouldCreateEntry); + bool shouldCreateFile, bool shouldCreateEntry); static void readLevels(const char *file, const char *component); diff --git a/vespalog/src/logger/llreader.cpp b/vespalog/src/logger/llreader.cpp index cb25b6747bf..200f4bb039d 100644 --- a/vespalog/src/logger/llreader.cpp +++ b/vespalog/src/logger/llreader.cpp @@ -1,17 +1,12 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <sys/time.h> #include "llreader.h" +#include <cstdlib> +#include <cstring> +#include <unistd.h> namespace ns_log { - InputBuf::InputBuf(int fd) : _inputfd(fd), _size(1000), diff --git a/vespalog/src/test/bufferedlogskiptest.cpp b/vespalog/src/test/bufferedlogskiptest.cpp index abb5705b612..29e5e119c34 100644 --- a/vespalog/src/test/bufferedlogskiptest.cpp +++ b/vespalog/src/test/bufferedlogskiptest.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/log/bufferedlogger.h> +#include <vespa/log/internal.h> #include <fstream> #include <iostream> @@ -15,7 +16,9 @@ using namespace std::literals::chrono_literals; struct TestTimer : public ns_log::Timer { uint64_t & _time; TestTimer(uint64_t & timeVar) : _time(timeVar) { } - ns_log::system_time getTimestamp() const override { return ns_log::system_time(std::chrono::microseconds(_time)); } + ns_log::system_time getTimestamp() const noexcept override { + return ns_log::system_time(std::chrono::microseconds(_time)); + } }; std::string readFile(const std::string& file) { @@ -71,8 +74,8 @@ void testSkipBufferOnDebug(const std::string& file, uint64_t & timer) void reset(uint64_t & timer) { timer = 0; ns_log::BufferedLogger::instance().setMaxCacheSize(10); - ns_log::BufferedLogger::instance().setMaxEntryAge(300s); - ns_log::BufferedLogger::instance().setCountFactor(5s); + ns_log::BufferedLogger::instance().setMaxEntryAge(300); + ns_log::BufferedLogger::instance().setCountFactor(5); } int diff --git a/vespalog/src/test/bufferedlogtest.cpp b/vespalog/src/test/bufferedlogtest.cpp index d3fc1c28d63..a2dfdd7c6b8 100644 --- a/vespalog/src/test/bufferedlogtest.cpp +++ b/vespalog/src/test/bufferedlogtest.cpp @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include <vespa/log/bufferedlogger.h> +#include <vespa/log/internal.h> #include "bufferedlogtest.logger1.h" #include "bufferedlogtest.logger2.h" @@ -19,7 +20,9 @@ using namespace std::literals::chrono_literals; struct TestTimer : public ns_log::Timer { uint64_t & _time; TestTimer(uint64_t & timeVar) : _time(timeVar) { } - ns_log::system_time getTimestamp() const override { return ns_log::system_time(std::chrono::microseconds(_time)); } + ns_log::system_time getTimestamp() const noexcept override { + return ns_log::system_time(std::chrono::microseconds(_time)); + } }; std::string readFile(const std::string& file) { @@ -122,9 +125,9 @@ void testThatEntriesWithHighCountsAreEventuallyRemoved( // Should eventually throw out the entries with high count timer = 10 * 1000000 + 4; // Make sure we don't remove due to age. - ns_log::BufferedLogger::instance().setMaxEntryAge(1000000s); + ns_log::BufferedLogger::instance().setMaxEntryAge(1000000); // Let each count, count for 5 seconds. - ns_log::BufferedLogger::instance().setCountFactor(5s); + ns_log::BufferedLogger::instance().setCountFactor(5); LOGBM(info, "Starting up, using logfile %s", file.c_str()); timer = 100 * 1000000 + 4; @@ -157,9 +160,9 @@ void testThatEntriesExpire( // Test that we don't keep entries longer than max age timer = 10 * 1000000 + 4; // Time out after 120 seconds - ns_log::BufferedLogger::instance().setMaxEntryAge(120s); + ns_log::BufferedLogger::instance().setMaxEntryAge(120); // Let counts count much, so they expire due to time instead - ns_log::BufferedLogger::instance().setCountFactor(100000s); + ns_log::BufferedLogger::instance().setCountFactor(100000); LOGBM(info, "Starting up, using logfile %s", file.c_str()); timer = 100 * 1000000 + 4; @@ -227,9 +230,9 @@ void testThatHighCountEntriesDontStarveOthers( std::cerr << "testThatHighCountEntriesDontStarveOthers ...\n"; timer = 10 * 1000000 + 4; // Long time out, we don't want to rely on timeout to prevent starvation - ns_log::BufferedLogger::instance().setMaxEntryAge(12000000s); + ns_log::BufferedLogger::instance().setMaxEntryAge(12000000); // Let counts count much, so they score high - ns_log::BufferedLogger::instance().setCountFactor(100000s); + ns_log::BufferedLogger::instance().setCountFactor(100000); LOGBM(info, "Starting up, using logfile %s", file.c_str()); timer = 100 * 1000000; @@ -382,8 +385,8 @@ void testNonBufferedLoggerTriggersBufferedLogTrim(const std::string& file, void reset(uint64_t& timer) { timer = 0; - ns_log::BufferedLogger::instance().setMaxEntryAge(300s); - ns_log::BufferedLogger::instance().setCountFactor(5s); + ns_log::BufferedLogger::instance().setMaxEntryAge(300); + ns_log::BufferedLogger::instance().setCountFactor(5); } int diff --git a/vespalog/src/test/threads/testthreads.cpp b/vespalog/src/test/threads/testthreads.cpp index 0c9b3a1cdb2..6a9d5c18a18 100644 --- a/vespalog/src/test/threads/testthreads.cpp +++ b/vespalog/src/test/threads/testthreads.cpp @@ -9,6 +9,7 @@ #include <unistd.h> #include <sys/stat.h> #include <cstdlib> +#include <cstring> #include <vector> using std::string; diff --git a/vespalog/src/vespa/log/bufferedlogger.cpp b/vespalog/src/vespa/log/bufferedlogger.cpp index 7ad878a568c..c589e0ae424 100644 --- a/vespalog/src/vespa/log/bufferedlogger.cpp +++ b/vespalog/src/vespa/log/bufferedlogger.cpp @@ -1,9 +1,9 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "bufferedlogger.h" +#include "internal.h" #include <boost/multi_index_container.hpp> #include <boost/multi_index/identity.hpp> -#include <boost/multi_index/member.hpp> #include <boost/multi_index/mem_fun.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/sequenced_index.hpp> @@ -208,16 +208,25 @@ BufferedLogger::~BufferedLogger() } namespace { - typedef boost::multi_index::nth_index< - BackingBuffer::LogCacheFront, 0>::type LogCacheFrontTimestamp; - typedef boost::multi_index::nth_index< - BackingBuffer::LogCacheFront, 1>::type LogCacheFrontToken; - typedef boost::multi_index::nth_index< - BackingBuffer::LogCacheBack, 0>::type LogCacheBackTimestamp; - typedef boost::multi_index::nth_index< - BackingBuffer::LogCacheBack, 1>::type LogCacheBackToken; - typedef boost::multi_index::nth_index< - BackingBuffer::LogCacheBack, 2>::type LogCacheBackAge; + +typedef boost::multi_index::nth_index< + BackingBuffer::LogCacheFront, 0>::type LogCacheFrontTimestamp; +typedef boost::multi_index::nth_index< + BackingBuffer::LogCacheFront, 1>::type LogCacheFrontToken; +typedef boost::multi_index::nth_index< + BackingBuffer::LogCacheBack, 0>::type LogCacheBackTimestamp; +typedef boost::multi_index::nth_index< + BackingBuffer::LogCacheBack, 1>::type LogCacheBackToken; +typedef boost::multi_index::nth_index< + BackingBuffer::LogCacheBack, 2>::type LogCacheBackAge; + +struct TimeStampWrapper : public Timer { + TimeStampWrapper(system_time timeStamp) : _timeStamp(timeStamp) {} + system_time getTimestamp() const noexcept override { return _timeStamp; } + + system_time _timeStamp; +}; + } void @@ -260,7 +269,7 @@ BackingBuffer::logImpl(Logger& l, Logger::LogLevel level, _cacheBack.get<1>().replace(it2, copy); } else { // If entry didn't already exist, add it to the cache and log it - l.doLogCore(entry._timestamp, level, file, line, message.c_str(), message.size()); + l.doLogCore(TimeStampWrapper(entry._timestamp), level, file, line, message.c_str(), message.size()); _cacheFront.push_back(entry); } trimCache(entry._timestamp); @@ -335,7 +344,7 @@ BackingBuffer::log(const Entry& e) const << " times since " << count_s(e._timestamp.time_since_epoch()) << "." << std::setw(6) << std::setfill('0') << (count_us(e._timestamp.time_since_epoch()) % 1000000) << ")"; - e._logger->doLogCore(_timer->getTimestamp(), e._level, e._file.c_str(), + e._logger->doLogCore(*_timer, e._level, e._file.c_str(), e._line, ost.str().c_str(), ost.str().size()); } } @@ -367,13 +376,13 @@ BufferedLogger::setMaxCacheSize(uint32_t size) { } void -BufferedLogger::setMaxEntryAge(duration maxAge) { - _backing->_maxEntryAge = maxAge; +BufferedLogger::setMaxEntryAge(uint64_t seconds) { + _backing->_maxEntryAge = std::chrono::seconds(seconds); } void -BufferedLogger::setCountFactor(duration factor) { - _backing->_countFactor = factor; +BufferedLogger::setCountFactor(uint64_t seconds) { + _backing->_countFactor = std::chrono::seconds(seconds); } /** Set a fake timer to use for log messages. Used in unit testing. */ diff --git a/vespalog/src/vespa/log/bufferedlogger.h b/vespalog/src/vespa/log/bufferedlogger.h index 31e194e63bb..f3aee2fb3f6 100644 --- a/vespalog/src/vespa/log/bufferedlogger.h +++ b/vespalog/src/vespa/log/bufferedlogger.h @@ -167,10 +167,10 @@ class BackingBuffer; class BufferedLogger { BackingBuffer *_backing; - BufferedLogger(const BufferedLogger & buf); - BufferedLogger & operator = (const BufferedLogger & buf); public: + BufferedLogger(const BufferedLogger & buf) = delete; + BufferedLogger & operator = (const BufferedLogger & buf) = delete; BufferedLogger(); ~BufferedLogger(); @@ -178,8 +178,8 @@ public: // to easier be able to test all aspects of the buffer, and be independent // of the default settings for applications void setMaxCacheSize(uint32_t size); - void setMaxEntryAge(duration seconds); - void setCountFactor(duration factor); + void setMaxEntryAge(uint64_t seconds); + void setCountFactor(uint64_t seconds); void doLog(Logger&, Logger::LogLevel level, const char *file, int line, const std::string& token, @@ -188,9 +188,6 @@ public: /** Empty buffer and write all log entries in it. */ void flush(); - /** Gives all current content of log buffer. Useful for debugging. */ - std::string toString() const; - /** Set a fake timer to use for log messages. Used in unit testing. */ void setTimer(std::unique_ptr<Timer> timer); diff --git a/vespalog/src/vespa/log/component.cpp b/vespalog/src/vespa/log/component.cpp index 009a69ad0c5..36b1d15e457 100644 --- a/vespalog/src/vespa/log/component.cpp +++ b/vespalog/src/vespa/log/component.cpp @@ -9,6 +9,7 @@ LOG_SETUP_INDIRECT(".log.control", "$Id$"); #include "component.h" #include "control-file.h" #include "internal.h" +#include <cstring> namespace ns_log { diff --git a/vespalog/src/vespa/log/internal.h b/vespalog/src/vespa/log/internal.h index c25c7cc44b6..7e6bf16f39f 100644 --- a/vespalog/src/vespa/log/internal.h +++ b/vespalog/src/vespa/log/internal.h @@ -3,6 +3,7 @@ #include <string> #include <cstdlib> +#include <chrono> namespace ns_log { @@ -20,4 +21,24 @@ public: [[nodiscard]] const char *what() const { return _what.c_str(); } }; +using system_time = std::chrono::system_clock::time_point; +using duration = std::chrono::nanoseconds; + +constexpr int64_t +count_s(duration d) noexcept { + return std::chrono::duration_cast<std::chrono::seconds>(d).count(); +} + +constexpr int64_t +count_us(duration d) noexcept { + return std::chrono::duration_cast<std::chrono::microseconds>(d).count(); +} + +// XXX this is way too complicated, must be some simpler way to do this +/** Timer class used to retrieve timestamp, such that we can override in test */ +struct Timer { + virtual ~Timer() = default; + virtual system_time getTimestamp() const noexcept; +}; + } // end namespace ns_log diff --git a/vespalog/src/vespa/log/llparser.cpp b/vespalog/src/vespa/log/llparser.cpp index 1585b9fde33..063220e50ef 100644 --- a/vespalog/src/vespa/log/llparser.cpp +++ b/vespalog/src/vespa/log/llparser.cpp @@ -4,6 +4,7 @@ #include "llparser.h" #include "internal.h" #include <cstdlib> +#include <cstring> #include <unistd.h> #include <sys/time.h> #include <cassert> diff --git a/vespalog/src/vespa/log/log-target-file.cpp b/vespalog/src/vespa/log/log-target-file.cpp index 4337d6b5bbb..87a9810e3c7 100644 --- a/vespalog/src/vespa/log/log-target-file.cpp +++ b/vespalog/src/vespa/log/log-target-file.cpp @@ -1,15 +1,15 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include "log.h" +LOG_SETUP(".log"); +#include "log-target-file.h" +#include "internal.h" + #include <unistd.h> #include <cstring> #include <fcntl.h> #include <cerrno> #include <cassert> -#include "log.h" -LOG_SETUP(".log"); -#include "log-target-file.h" -#include "internal.h" - namespace ns_log { #ifndef O_LARGEFILE diff --git a/vespalog/src/vespa/log/log.cpp b/vespalog/src/vespa/log/log.cpp index 9ca993b84fc..73cbeef08aa 100644 --- a/vespalog/src/vespa/log/log.cpp +++ b/vespalog/src/vespa/log/log.cpp @@ -6,7 +6,6 @@ LOG_SETUP_INDIRECT(".log", "$Id$"); #undef LOG #define LOG LOG_INDIRECT -#include "lock.h" #include "log-target.h" #include "internal.h" #include "control-file.h" @@ -15,13 +14,15 @@ LOG_SETUP_INDIRECT(".log", "$Id$"); #include <vespa/defaults.h> #include <cassert> #include <cstdarg> +#include <cstring> +#include <cinttypes> #include <unistd.h> #include <sys/time.h> namespace ns_log { system_time -Timer::getTimestamp() const { +Timer::getTimestamp() const noexcept { return std::chrono::system_clock::now(); } @@ -131,7 +132,7 @@ Logger::ensureHostname() Logger::Logger(const char *name, const char *rcsId) : _logLevels(ControlFile::defaultLevels()), - _timer(new Timer()) + _timer(std::make_unique<Timer>()) { _numInstances++; memset(_rcsId, 0, sizeof(_rcsId)); @@ -168,7 +169,6 @@ Logger::Logger(const char *name, const char *rcsId) } } - Logger::~Logger() { _numInstances--; @@ -186,6 +186,10 @@ Logger::~Logger() } } +void +Logger::setTimer(std::unique_ptr<Timer> timer) { + _timer = std::move(timer); +} int Logger::setRcsId(const char *id) @@ -216,7 +220,7 @@ Logger::tryLog(int sizeofPayload, LogLevel level, const char *file, int line, co const int actualSize = vsnprintf(payload, sizeofPayload, fmt, args); if (actualSize < sizeofPayload) { - doLogCore(_timer->getTimestamp(), level, file, line, payload, actualSize); + doLogCore(*_timer, level, file, line, payload, actualSize); } delete[] payload; return actualSize; @@ -238,9 +242,10 @@ Logger::doLog(LogLevel level, const char *file, int line, const char *fmt, ...) } void -Logger::doLogCore(system_time timestamp, LogLevel level, +Logger::doLogCore(const Timer & timer, LogLevel level, const char *file, int line, const char *msg, size_t msgSize) { + system_time timestamp = timer.getTimestamp(); const size_t sizeofEscapedPayload(msgSize*4+1); const size_t sizeofTotalMessage(sizeofEscapedPayload + 1000); auto escapedPayload = std::make_unique<char[]>(sizeofEscapedPayload); @@ -349,35 +354,20 @@ Logger::doEventStarted(const char *name) void Logger::doEventStopped(const char *name, pid_t pid, int exitCode) { - doLog(event, "", 0, "stopped/1 name=\"%s\" pid=%d exitcode=%d", name, - static_cast<int>(pid), exitCode); -} - -void -Logger::doEventReloading(const char *name) -{ - doLog(event, "", 0, "reloading/1 name=\"%s\"", name); -} - -void -Logger::doEventReloaded(const char *name) -{ - doLog(event, "", 0, "reloaded/1 name=\"%s\"", name); + doLog(event, "", 0, "stopped/1 name=\"%s\" pid=%d exitcode=%d", name, static_cast<int>(pid), exitCode); } void Logger::doEventCrash(const char *name, pid_t pid, int signal) { - doLog(event, "", 0, "crash/1 name=\"%s\" pid=%d signal=\"%s\"", name, pid, - strsignal(signal)); + doLog(event, "", 0, "crash/1 name=\"%s\" pid=%d signal=\"%s\"", name, pid, strsignal(signal)); } void Logger::doEventProgress(const char *name, double value, double total) { if (total > 0) { - doLog(event, "", 0, "progress/1 name=\"%s\" value=%.18g total=%.18g", - name, value, total); + doLog(event, "", 0, "progress/1 name=\"%s\" value=%.18g total=%.18g", name, value, total); } else { doLog(event, "", 0, "progress/1 name=\"%s\" value=%.18g", name, value); } diff --git a/vespalog/src/vespa/log/log.h b/vespalog/src/vespa/log/log.h index 88d24ba7e18..857bf4f2b97 100644 --- a/vespalog/src/vespa/log/log.h +++ b/vespalog/src/vespa/log/log.h @@ -2,17 +2,9 @@ #pragma once #include <memory> -#include <cstdint> #include <new> // for placement new -#include <cstdlib> // for malloc -#include <cstring> // for memset -#include <cstdarg> // for va_list -#include <cinttypes> -#include <chrono> #include <sys/types.h> // for pid_t - - /** * If this macro is defined, the regular LOG calls will go through the * buffered logger, using the whole messages as tokens. @@ -27,7 +19,7 @@ static ns_log::Logger ns_log_logger(__VA_ARGS__) // NOLINT #define LOG_SETUP_INDIRECT(x, id) \ -static ns_log::Logger *ns_log_indirect_logger=NULL; \ +static ns_log::Logger *ns_log_indirect_logger=nullptr; \ static bool logInitialised = false; \ static const char *logName = x; \ static const char *indirectRcsId = id @@ -37,9 +29,6 @@ static const char *indirectRcsId = id #define LOG_INDIRECT_WOULD_LOG(levelName) \ ns_log_indirect_logger->wants(ns_log::Logger::levelName) -#define LOG_RCSID(x) \ -static int log_dummmy __attribute__((unused)) = ns_log_logger.setRcsId(x) - // Define LOG if not using log buffer. Otherwise log buffer will define them #ifndef VESPA_LOG_USELOGBUFFERFORREGULARLOG #define LOG(level, ...) \ @@ -147,25 +136,7 @@ namespace ns_log { class LogTarget; class ControlFile; -using system_time = std::chrono::system_clock::time_point; -using duration = std::chrono::nanoseconds; - -constexpr int64_t -count_s(duration d) { - return std::chrono::duration_cast<std::chrono::seconds>(d).count(); -} - -constexpr int64_t -count_us(duration d) { - return std::chrono::duration_cast<std::chrono::microseconds>(d).count(); -} - -// XXX this is way too complicated, must be some simpler way to do this -/** Timer class used to retrieve timestamp, such that we can override in test */ -struct Timer { - virtual ~Timer() = default; - virtual system_time getTimestamp() const; -}; +struct Timer; class Logger { public: @@ -182,9 +153,6 @@ public: static bool fakePid; private: - Logger(const Logger &); - Logger& operator =(const Logger &); - unsigned int *_logLevels; static char _prefix[64]; @@ -214,6 +182,8 @@ private: public: ~Logger(); explicit Logger(const char *name, const char *rcsId = nullptr); + Logger(const Logger &) = delete; + Logger & operator=(const Logger &) = delete; int setRcsId(const char *rcsId); static const char *levelName(LogLevel level); @@ -227,14 +197,12 @@ public: * * @param timestamp Time in microseconds. */ - void doLogCore(system_time timestamp, LogLevel level, + void doLogCore(const Timer &, LogLevel level, const char *file, int line, const char *msg, size_t msgSize); void doEventStarting(const char *name); void doEventStopping(const char *name, const char *why); void doEventStarted(const char *name); void doEventStopped(const char *name, pid_t pid, int exitCode); - void doEventReloading(const char *name); - void doEventReloaded(const char *name); void doEventCrash(const char *name, pid_t pid, int signal); void doEventProgress(const char *name, double value, double total = 0); void doEventCount(const char *name, uint64_t value); @@ -242,7 +210,7 @@ public: void doEventState(const char *name, const char *value); // Only for unit testing - void setTimer(std::unique_ptr<Timer> timer) { _timer = std::move(timer); } + void setTimer(std::unique_ptr<Timer> timer); // Only for internal use static LogTarget *getCurrentTarget(); |