Skip to content

Commit

Permalink
Update for v1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
itismadness committed Nov 6, 2018
1 parent 269d395 commit 8ed24eb
Show file tree
Hide file tree
Showing 58 changed files with 13,318 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ autom4te.cache/
Makefile
.deps/
src/ocelot
CMakeLists.txt
CMakeLists.txt
/ocelot.conf
9 changes: 7 additions & 2 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
-- 1.1 (2017-10-xx)
..
-- 1.1 (2018-10-29)
Move to spdlog (https://github.com/gabime/spdlog)to handle logging instead of cout
spdlog is vendored under src/, currently using v0.13.0
Add logging directive to config to configure how Ocelot logs and where it logs
Add deamon (--daemon, -d) to run Ocelot as a daemon
Move source code into src/ directory
Add Vagrantfile and Dockerfile for running Ocelot

-- 1.0 (2015-01-26)
NOTE: This version requires the following database change:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Ocelot is a BitTorrent tracker written in C++ for the [Gazelle](http://whatcd.gi

## Installation

### Debian Jessie
### Debian Stretch
```bash
sudo apt-get install pkg-config libev-dev libboost-all-dev
./configure --with-boost-libdir=/usr/lib/x86_64-linux-gnu
Expand Down
18 changes: 13 additions & 5 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,22 @@
# vi: set ft=ruby :

$script = <<SCRIPT
sudo apt-get -y install build-essential autoconf
sudo apt-get -y install libboost-iostreams-dev libboost-system-dev
sudo apt-get -y install libev-dev
sudo apt-get -y install libmysqlclient-dev libmysql++-dev
apt-get update
apt-get -y install \
autoconf \
build-essential \
default-libmysqlclient-dev \
libboost-iostreams-dev \
libboost-system-dev \
libev-dev \
libmysql++-dev \
pkg-config \
mariadb-client \
mariadb-server
SCRIPT

Vagrant.configure("2") do |config|
config.vm.box = "debian/contrib-jessie64"
config.vm.box = "debian/contrib-stretch64"

config.vm.synced_folder ".", "/vagrant"
config.vm.provision "shell", inline: $script
Expand Down
3 changes: 3 additions & 0 deletions ocelot.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@ del_reason_lifetime = 86400
reap_peers_interval = 1800
schedule_interval = 3

log = false
log_path = /tmp/ocelot

readonly = false
10 changes: 8 additions & 2 deletions src/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,24 @@
//---------- Connection mother - spawns middlemen and lets them deal with the connection

connection_mother::connection_mother(config * conf, worker * worker_obj, mysql * db_obj, site_comm * sc_obj, schedule * sched) : work(worker_obj), db(db_obj) {
logger = spdlog::get("logger");

// Handle config stuff first
load_config(conf);

listen_socket = create_listen_socket();

// We failed to create the socket, so no point in running Ocelot
if (listen_socket == 0) {
logger->critical("Failed to create socket for Ocelot. Exiting.");
exit(1);
}

listen_event.set<connection_mother, &connection_mother::handle_connect>(this);
listen_event.start(listen_socket, ev::READ);
// Create libev timer
schedule_event.set<schedule, &schedule::handle>(sched);
schedule_event.start(sched->schedule_interval, sched->schedule_interval); // After interval, every interval

logger = spdlog::get("logger");
}

void connection_mother::load_config(config * conf) {
Expand Down
8 changes: 5 additions & 3 deletions src/ocelot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <thread>
#include <sys/stat.h>
#include <syslog.h>
#include <spdlog/spdlog.h>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "ocelot.h"
#include "config.h"
#include "db.h"
Expand Down Expand Up @@ -131,10 +133,10 @@ int main(int argc, char **argv) {

std::vector<spdlog::sink_ptr> sinks;
if (!conf->get_bool("daemonize") && !daemonize) {
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_st>());
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_mt>());
}
if (conf->get_bool("log") && !conf->get_str("log_path").empty()) {
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_st>(conf->get_str("log_path"), 23, 59));
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_mt>(conf->get_str("log_path"), 23, 59));
}

auto combined_logger = std::make_shared<spdlog::logger>("logger", begin(sinks), end(sinks));
Expand Down
1 change: 1 addition & 0 deletions src/site_comm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using boost::asio::ip::tcp;

site_comm::site_comm(config * conf) : t_active(false) {
logger = spdlog::get("logger");
load_config(conf);
}

Expand Down
87 changes: 87 additions & 0 deletions src/spdlog/async.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

//
// Copyright(c) 2018 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#pragma once

//
// Async logging using global thread pool
// All loggers created here share same global thread pool.
// Each log message is pushed to a queue along withe a shared pointer to the
// logger.
// If a logger deleted while having pending messages in the queue, it's actual
// destruction will defer
// until all its messages are processed by the thread pool.
// This is because each message in the queue holds a shared_ptr to the
// originating logger.

#include "spdlog/async_logger.h"
#include "spdlog/details/registry.h"
#include "spdlog/details/thread_pool.h"

#include <memory>
#include <mutex>

namespace spdlog {

namespace details {
static const size_t default_async_q_size = 8192;
}

// async logger factory - creates async loggers backed with thread pool.
// if a global thread pool doesn't already exist, create it with default queue
// size of 8192 items and single thread.
template<async_overflow_policy OverflowPolicy = async_overflow_policy::block>
struct async_factory_impl
{
template<typename Sink, typename... SinkArgs>
static std::shared_ptr<async_logger> create(const std::string &logger_name, SinkArgs &&... args)
{
auto &registry_inst = details::registry::instance();

// create global thread pool if not already exists..
std::lock_guard<std::recursive_mutex> tp_lock(registry_inst.tp_mutex());
auto tp = registry_inst.get_tp();
if (tp == nullptr)
{
tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1);
registry_inst.set_tp(tp);
}

auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
auto new_logger = std::make_shared<async_logger>(logger_name, std::move(sink), std::move(tp), OverflowPolicy);
registry_inst.register_and_init(new_logger);
return new_logger;
}
};

using async_factory = async_factory_impl<async_overflow_policy::block>;
using async_factory_nonblock = async_factory_impl<async_overflow_policy::overrun_oldest>;

template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async(const std::string &logger_name, SinkArgs &&... sink_args)
{
return async_factory::create<Sink>(logger_name, std::forward<SinkArgs>(sink_args)...);
}

template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async_nb(const std::string &logger_name, SinkArgs &&... sink_args)
{
return async_factory_nonblock::create<Sink>(logger_name, std::forward<SinkArgs>(sink_args)...);
}

// set global thread pool.
inline void init_thread_pool(size_t q_size, size_t thread_count)
{
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count);
details::registry::instance().set_tp(std::move(tp));
}

// get the global thread pool.
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool()
{
return details::registry::instance().get_tp();
}
} // namespace spdlog
73 changes: 73 additions & 0 deletions src/spdlog/async_logger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#pragma once

// Very fast asynchronous logger (millions of logs per second on an average
// desktop)
// Uses pre allocated lockfree queue for maximum throughput even under large
// number of threads.
// Creates a single back thread to pop messages from the queue and log them.
//
// Upon each log write the logger:
// 1. Checks if its log level is enough to log the message
// 2. Push a new copy of the message to a queue (or block the caller until
// space is available in the queue)
// 3. will throw spdlog_ex upon log exceptions
// Upon destruction, logs all remaining messages in the queue before
// destructing..

#include "spdlog/common.h"
#include "spdlog/logger.h"

#include <chrono>
#include <memory>
#include <string>

namespace spdlog {

// Async overflow policy - block by default.
enum class async_overflow_policy
{
block, // Block until message can be enqueued
overrun_oldest // Discard oldest message in the queue if full when trying to
// add new item.
};

namespace details {
class thread_pool;
}

class async_logger final : public std::enable_shared_from_this<async_logger>, public logger
{
friend class details::thread_pool;

public:
template<typename It>
async_logger(std::string logger_name, It begin, It end, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block);

async_logger(std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block);

async_logger(std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp,
async_overflow_policy overflow_policy = async_overflow_policy::block);

std::shared_ptr<logger> clone(std::string new_name) override;

protected:
void sink_it_(details::log_msg &msg) override;
void flush_() override;

void backend_log_(const details::log_msg &incoming_log_msg);
void backend_flush_();

private:
std::weak_ptr<details::thread_pool> thread_pool_;
async_overflow_policy overflow_policy_;
};
} // namespace spdlog

#include "details/async_logger_impl.h"
Loading

0 comments on commit 8ed24eb

Please sign in to comment.