boost日志库的使用

在boost中有自带的日志库供开发人员使用但效率不是最高的:
加入头文件#include <boost/log/trivial.hpp>即可引入日志库

boost中的log库有以下六种级别:

BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
BOOST_LOG_TRIVIAL(info) << "An informational severity message";
BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
BOOST_LOG_TRIVIAL(error) << "An error severity message";
BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

在需要的地方加入即可输出log语句
在这里插入图片描述

使用boost log库需要在makefile文件加入-DBOOST_LOG_DYN_LINK:

server:main.cpp structHeader.cpp Protocal.pb.cc Protocal.pb.h chat_message.h structHeader.h JsonObject.h
	g++ -DBOOST_LOG_DYN_LINK -O2 -g -std=c++14 -o server main.cpp structHeader.cpp Protocal.pb.cc -lboost_system -lboost_log -lboost_log_setup -lboost_thread -lboost_serialization -lpthread -lprotobuf
client:client.cpp structHeader.cpp Protocal.pb.cc Protocal.pb.h chat_message.h structHeader.h JsonObject.h
	g++ -O2 -g -std=c++14 -o client client.cpp structHeader.cpp Protocal.pb.cc -lboost_system -lboost_serialization -lpthread -lprotobuf

可以通过以下方式对log信息进行过滤:

//头文件加入:
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
//一般写在init函数里:
void init() {
	boost::log::core::get()->set_filter
		(
		 boost::log::trivial::severity >= boost::log::trivial::info
		);
}

boostlog记录到文件里最简单的方式:

//头文件加入:
#include <boost/log/utility/steup/file.hpp>
//在init()函数中加入以下语句即可:
boost::log::add_file_log("sample.log")

boostlog记录到文件时可以在makefile文件加入-lboost_thread提高效率,因为写文件是在别的线程里做的

更多详细使用说明参考boost log官方文档

以下是加了boost日志库的asio聊天室完整服务器代码部分:

#include "chat_message.h"
#include "JsonObject.h"
#include "Protocal.pb.h"

#include <boost/asio.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>

#include <chrono>
#include <deque>
#include <iostream>
#include <list>
#include <memory>
#include <set>
#include <thread>
#include <utility>
#include <mutex>

#include <cstdlib>

using boost::asio::ip::tcp;

//----------------------------------------------------------------------

using chat_message_queue = std::deque<chat_message>;
using chat_message_queue2 = std::list<chat_message>;
//----------------------------------------------------------------------

// stread_clock
std::chrono::system_clock::time_point base;

//----------------------------------------------------------------------

class chat_session;
using chat_session_ptr = std::shared_ptr<chat_session>;
class chat_room {
public:
	chat_room(boost::asio::io_service& io_service) : m_strand(io_service) {}
public:
	void join(chat_session_ptr);
	void leave(chat_session_ptr);
	void deliver(const chat_message&);
private:
	boost::asio::io_service::strand m_strand;
	//std::mutex m_mutex;
  std::set<chat_session_ptr> participants_;
  enum { max_recent_msgs = 100 };
  chat_message_queue recent_msgs_;
};
//----------------------------------------------------------------------

class chat_session : public std::enable_shared_from_this<chat_session> {
public:
  chat_session(tcp::socket socket, chat_room &room)
      : socket_(std::move(socket)), room_(room),
			m_strand(socket_.get_io_service()) {}

  void start() {
    room_.join(shared_from_this());
    do_read_header();
  }

  void deliver(const chat_message &msg) {
		// first false
		m_strand.post([this, msg]{
    bool write_in_progress = !write_msgs_.empty();
    write_msgs_.push_back(msg);
    if (!write_in_progress) {
			// first
      do_write();
    }});
  }

private:
  void do_read_header() {
    auto self(shared_from_this());
    boost::asio::async_read(
        socket_,
        boost::asio::buffer(read_msg_.data(), chat_message::header_length),
				m_strand.wrap(
        [this, self](boost::system::error_code ec, std::size_t /*length*/) {
          if (!ec && read_msg_.decode_header()) {
            do_read_body();
          } else {
            std::cout << "Player leave the room\n";
            room_.leave(shared_from_this());
          }
        }));
  }

  void do_read_body() {
    auto self(shared_from_this());
    boost::asio::async_read(
        socket_, boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
				m_strand.wrap(
        [this, self](boost::system::error_code ec, std::size_t /*length*/) {
          if (!ec) {
            //room_.deliver(read_msg_);
						handleMessage();
            do_read_header();
          } else {
            room_.leave(shared_from_this());
          }
        }));
  }

  template <typename T> T toObject() {
    T obj;
    std::stringstream ss(std::string(
        read_msg_.body(), read_msg_.body() + read_msg_.body_length()));
    boost::archive::text_iarchive oa(ss);
    oa &obj;
    return obj;
  }

  bool fillProtobuf(::google::protobuf::Message* msg) {
    std::string ss(
        read_msg_.body(), read_msg_.body() + read_msg_.body_length());
		auto ok = msg->ParseFromString(ss);
    return ok;
  }

	ptree toPtree() {
		ptree obj;
		std::stringstream ss(
				std::string(read_msg_.body(),
					read_msg_.body() + read_msg_.body_length()));
		boost::property_tree::read_json(ss, obj);
		return obj;
	}

  void handleMessage() {
		auto n = std::chrono::system_clock::now() - base;
		std::cout << "i'm in " << std::this_thread::get_id() << " time "
			<< std::chrono::duration_cast<std::chrono::milliseconds>(n).count() << std::endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(3));
    if (read_msg_.type() == MT_BIND_NAME) {
			PBindName bindName;
			if(fillProtobuf(&bindName))
				m_name = bindName.name();
    } else if (read_msg_.type() == MT_CHAT_INFO) {
			PChat chat;
			if(!fillProtobuf(&chat)) return;
			m_chatInformation = chat.information();

      auto rinfo = buildRoomInfo();
      chat_message msg;
      msg.setMessage(MT_ROOM_INFO, rinfo);
      room_.deliver(msg);

    } else {
      // not valid msg do nothing
    }
  }

  void do_write() {
    auto self(shared_from_this());
    boost::asio::async_write(
        socket_, boost::asio::buffer(write_msgs_.front().data(),
                                     write_msgs_.front().length()),
				m_strand.wrap(
        [this, self](boost::system::error_code ec, std::size_t /*length*/) {
          if (!ec) {
            write_msgs_.pop_front();
            if (!write_msgs_.empty()) {
              do_write();
            }
          } else {
            room_.leave(shared_from_this());
          }
        }));
  }

  tcp::socket socket_;
  chat_room &room_;
  chat_message read_msg_;
  chat_message_queue write_msgs_;
	std::string m_name;
	std::string m_chatInformation;
	boost::asio::io_service::strand m_strand;
	std::string buildRoomInfo() const {
		PRoomInformation roomInfo;
		roomInfo.set_name(m_name);
		roomInfo.set_information(m_chatInformation);
		std::string out;
		auto ok = roomInfo.SerializeToString(&out);
		assert(ok);
		return out;
	}
//	RoomInformation buildRoomInfo() const {
//		RoomInformation info;
//		info.name.nameLen = m_name.size();
//		std::memcpy(info.name.name, m_name.data(), m_name.size());
//		info.chat.infoLen = m_chatInformation.size();
//		std::memcpy(info.chat.information, m_chatInformation.data(),
//				m_chatInformation.size());
//		return info;
//	}
};


  void chat_room::join(chat_session_ptr participant) {
		//std::lock_guard<std::mutex> lock(m_mutex);
		m_strand.post([this, participant]{
				participants_.insert(participant);
				for (const auto& msg : recent_msgs_)
				participant->deliver(msg);
				});
  }

  void chat_room::leave(chat_session_ptr participant) {
		//std::lock_guard<std::mutex> lock(m_mutex);
		m_strand.post([this,participant]{
    participants_.erase(participant);});
  }

  void chat_room::deliver(const chat_message &msg) {
		//std::lock_guard<std::mutex> lock(m_mutex);
		m_strand.post([this, msg]{
    recent_msgs_.push_back(msg);
    while (recent_msgs_.size() > max_recent_msgs)
      recent_msgs_.pop_front();

    for (auto& participant : participants_)
      participant->deliver(msg);
		});
  }


//----------------------------------------------------------------------

class chat_server {
public:
  chat_server(boost::asio::io_service &io_service,
              const tcp::endpoint &endpoint)
      : acceptor_(io_service, endpoint), socket_(io_service), room_(io_service) {
    do_accept();
  }

private:
  void do_accept() {
    acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
      if (!ec) {
        auto session =
            std::make_shared<chat_session>(std::move(socket_), room_);
        session->start();
      }

      do_accept();
    });
  }

  tcp::acceptor acceptor_;
  tcp::socket socket_;
  chat_room room_;
};

//----------------------------------------------------------------------
void init() {
	boost::log::core::get()->set_filter
		(
		 boost::log::trivial::severity >= boost::log::trivial::info
		);
}

int main(int argc, char *argv[]) {
  try {
		GOOGLE_PROTOBUF_VERIFY_VERSION;
		init();
		BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
		BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
		BOOST_LOG_TRIVIAL(info) << "An informational severity message";
		BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
		BOOST_LOG_TRIVIAL(error) << "An error severity message";
		BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
    if (argc < 2) {
      std::cerr << "Usage: chat_server <port> [<port> ...]\n";
      return 1;
    }
		base = std::chrono::system_clock::now();

    boost::asio::io_service io_service;

    std::list<chat_server> servers;
    for (int i = 1; i < argc; ++i) {
      tcp::endpoint endpoint(tcp::v4(), std::atoi(argv[i]));
      servers.emplace_back(io_service, endpoint);
    }

		std::vector<std::thread> threadGroup;
		for(int i = 0; i < 5; ++i) {
			threadGroup.emplace_back([&io_service, i]{
					std::cout << i << " name is " << std::this_thread::get_id() << std::endl;
					io_service.run();});
		}

		BOOST_LOG_TRIVIAL(info) << "main thread name is " << std::this_thread::get_id() << std::endl;
		io_service.run();
		for(auto& v : threadGroup) v.join();
  } catch (std::exception &e) {
		BOOST_LOG_TRIVIAL(error) << "Exception: " << e.what();
    std::cerr << "Exception: " << e.what() << "\n";
  }

	google::protobuf::ShutdownProtobufLibrary();
	BOOST_LOG_TRIVIAL(info) << "safe release all resource";
  return 0;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值