blob: d46f8dfd188c9c40ab9497f14e9a04d6e4fe0339 [file] [log] [blame]
/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* 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 "cobalt/network/cobalt_net_log.h"
#include <algorithm>
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/values.h"
#include "cobalt/network/net_log_logger.h"
namespace cobalt {
namespace network {
CobaltNetLog::CobaltNetLog(const FilePath& log_path,
net::NetLog::LogLevel level)
: base_log_level_(level), effective_log_level_(level) {
// Increment this once so the first event gets 1 rather than 0.
source_id_.GetNext();
net_log_logger_.reset(new NetLogLogger(log_path));
net_log_logger_->StartObserving(this);
}
CobaltNetLog::~CobaltNetLog() {
// Remove the observers we own before we're destroyed.
if (net_log_logger_.get()) RemoveThreadSafeObserver(net_log_logger_.get());
}
void CobaltNetLog::OnAddEntry(const net::NetLog::Entry& entry) {
base::AutoLock lock(lock_);
// Notify all of the log observers.
FOR_EACH_OBSERVER(ThreadSafeObserver, observers_, OnAddEntry(entry));
}
uint32 CobaltNetLog::NextID() {
return static_cast<uint32>(source_id_.GetNext());
}
net::NetLog::LogLevel CobaltNetLog::GetLogLevel() const {
base::subtle::Atomic32 log_level =
base::subtle::NoBarrier_Load(&effective_log_level_);
return static_cast<net::NetLog::LogLevel>(log_level);
}
void CobaltNetLog::AddThreadSafeObserver(
net::NetLog::ThreadSafeObserver* observer, LogLevel log_level) {
base::AutoLock lock(lock_);
observers_.AddObserver(observer);
OnAddObserver(observer, log_level);
UpdateLogLevel();
}
void CobaltNetLog::SetObserverLogLevel(
net::NetLog::ThreadSafeObserver* observer, LogLevel log_level) {
base::AutoLock lock(lock_);
DCHECK(observers_.HasObserver(observer));
OnSetObserverLogLevel(observer, log_level);
UpdateLogLevel();
}
void CobaltNetLog::RemoveThreadSafeObserver(
net::NetLog::ThreadSafeObserver* observer) {
base::AutoLock lock(lock_);
DCHECK(observers_.HasObserver(observer));
observers_.RemoveObserver(observer);
OnRemoveObserver(observer);
UpdateLogLevel();
}
void CobaltNetLog::UpdateLogLevel() {
lock_.AssertAcquired();
// Look through all the observers and find the finest granularity
// log level (higher values of the enum imply *lower* log levels).
LogLevel new_effective_log_level = base_log_level_;
ObserverListBase<ThreadSafeObserver>::Iterator it(observers_);
ThreadSafeObserver* observer;
while ((observer = it.GetNext()) != NULL) {
new_effective_log_level =
std::min(new_effective_log_level, observer->log_level());
}
base::subtle::NoBarrier_Store(&effective_log_level_, new_effective_log_level);
}
} // namespace network
} // namespace cobalt