1    	// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2    	// vim: ts=8 sw=2 smarttab
3    	
4    	#ifndef __CEPH_LOG_ENTRY_H
5    	#define __CEPH_LOG_ENTRY_H
6    	
7    	#include "log/LogClock.h"
8    	
9    	#include "common/StackStringStream.h"
10   	
11   	#include "boost/container/small_vector.hpp"
12   	
13   	#include <pthread.h>
14   	
15   	#include <string_view>
16   	
17   	namespace ceph {
18   	namespace logging {
19   	
20   	class Entry {
21   	public:
22   	  using time = log_time;
23   	
24   	  Entry() = delete;
25   	  Entry(short pr, short sub) :
26   	    m_stamp(clock().now()),
27   	    m_thread(pthread_self()),
28   	    m_prio(pr),
29   	    m_subsys(sub)
30   	  {}
31   	  Entry(const Entry &) = default;
32   	  Entry& operator=(const Entry &) = default;
33   	  Entry(Entry &&e) = default;
34   	  Entry& operator=(Entry &&e) = default;
35   	  virtual ~Entry() = default;
36   	
37   	  virtual std::string_view strv() const = 0;
38   	  virtual std::size_t size() const = 0;
39   	
40   	  time m_stamp;
41   	  pthread_t m_thread;
42   	  short m_prio, m_subsys;
43   	
44   	private:
45   	  static log_clock& clock() {
46   	    static log_clock clock;
47   	    return clock;
48   	  }
49   	};
50   	
51   	/* This should never be moved to the heap! Only allocate this on the stack. See
52   	 * CachedStackStringStream for rationale.
53   	 */
54   	class MutableEntry : public Entry {
55   	public:
56   	  MutableEntry() = delete;
57   	  MutableEntry(short pr, short sub) : Entry(pr, sub) {}
58   	  MutableEntry(const MutableEntry&) = delete;
59   	  MutableEntry& operator=(const MutableEntry&) = delete;
60   	  MutableEntry(MutableEntry&&) = delete;
61   	  MutableEntry& operator=(MutableEntry&&) = delete;
62   	  ~MutableEntry() override = default;
63   	
64   	  std::ostream& get_ostream() {
65   	    return *cos;
66   	  }
67   	
68   	  std::string_view strv() const override {
69   	    return cos->strv();
70   	  }
71   	  std::size_t size() const override {
72   	    return cos->strv().size();
73   	  }
74   	
75   	private:
76   	  CachedStackStringStream cos;
77   	};
78   	
79   	class ConcreteEntry : public Entry {
80   	public:
81   	  ConcreteEntry() = delete;
82   	  ConcreteEntry(const Entry& e) : Entry(e) {
83   	    auto strv = e.strv();
(1) Event fun_call_w_exception: Called function throws an exception of type "std::length_error". [details]
84   	    str.reserve(strv.size());
85   	    str.insert(str.end(), strv.begin(), strv.end());
86   	  }
87   	  ConcreteEntry& operator=(const Entry& e) {
88   	    Entry::operator=(e);
89   	    auto strv = e.strv();
90   	    str.reserve(strv.size());
91   	    str.assign(strv.begin(), strv.end());
92   	    return *this;
93   	  }
94   	  ConcreteEntry(ConcreteEntry&& e) : Entry(e), str(std::move(e.str)) {}
95   	  ConcreteEntry& operator=(ConcreteEntry&& e) {
96   	    Entry::operator=(e);
97   	    str = std::move(e.str);
98   	    return *this;
99   	  }
100  	  ~ConcreteEntry() override = default;
101  	
102  	  std::string_view strv() const override {
103  	    return std::string_view(str.data(), str.size());
104  	  }
105  	  std::size_t size() const override {
106  	    return str.size();
107  	  }
108  	
109  	private:
110  	  boost::container::small_vector<char, 1024> str;
111  	};
112  	
113  	}
114  	}
115  	
116  	#endif
117