blob: 8eebc2211375b6a54f3d10a7e44f667f6979f9fb [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