00001:
00002:
00003:
00004:
00005:
00006:
00007:
00008:
00009:
000010:
000011:
000012:
000013:
000014:
000015:
000016:
000017:
000018:
000019:
000020:
000021:
000022:
000023:
000024:
000025:
000026:
000027:
000028:
000029:
000030:
000031:
000032:
000033:
000034:
000035:
000036:
000037:
000038:
000039:
000040:
000041:
000042:
000043:
000044:
000045:
000046:
000047:
000048:
000049:
000050:
000051:
000052:
000053:
000054:
000055:
000056:
000057:
000058:
000059:
000060:
000061:
000062:
000063:
000064:
000065:
000066:
000067:
000068:
000069:
000070:
000071:
000072:
000073:
000074:
000075:
000076:
000077:
000078:
000079:
000080:
000081:
000082:
000083:
000084:
000085:
000086:
000087:
000088:
000089:
000090:
000091:
000092:
000093:
000094:
000095:
000096:
000097:
000098:
000099:
0000100:
0000101:
0000102:
0000103:
0000104:
0000105:
0000106:
0000107:
0000108:
0000109:
0000110:
0000111:
0000112:
0000113:
0000114:
0000115:
0000116:
0000117:
0000118:
0000119:
0000120:
0000121:
0000122:
0000123:
0000124:
0000125:
0000126:
0000127:
0000128:
0000129:
0000130:
0000131:
0000132:
0000133:
0000134:
0000135:
0000136:
0000137:
0000138:
0000139:
0000140:
0000141:
0000142:
0000143:
0000144:
0000145:
0000146:
0000147:
0000148:
0000149:
0000150:
0000151:
0000152:
0000153:
0000154:
0000155:
0000156:
0000157:
0000158:
0000159:
0000160:
0000161:
0000162:
0000163:
0000164:
0000165:
0000166:
0000167:
0000168:
0000169:
0000170:
0000171:
0000172:
0000173:
0000174:
0000175:
0000176:
0000177:
0000178:
0000179:
0000180:
0000181:
0000182:
0000183:
0000184:
0000185:
0000186:
0000187:
0000188:
0000189:
0000190:
0000191:
0000192:
0000193:
0000194:
0000195:
0000196:
0000197:
0000198:
0000199:
0000200:
0000201:
0000202:
0000203:
0000204:
0000205:
0000206:
0000207:
0000208:
0000209:
0000210:
0000211:
0000212:
0000213:
0000214:
0000215:
0000216:
0000217:
0000218:
0000219:
0000220:
0000221:
0000222:
0000223:
0000224:
0000225:
0000226:
0000227:
0000228:
0000229:
0000230:
0000231:
0000232:
0000233:
0000234:
0000235:
0000236:
0000237:
0000238:
0000239:
0000240:
0000241:
0000242:
0000243:
0000244:
0000245:
0000246:
0000247:
0000248:
0000249:
0000250:
0000251:
0000252:
0000253:
0000254:
0000255:
0000256:
0000257:
0000258:
0000259:
0000260:
0000261:
0000262:
0000263:
0000264:
0000265:
0000266:
0000267:
0000268:
0000269:
0000270:
0000271:
0000272:
0000273:
0000274:
0000275:
0000276:
0000277:
0000278:
0000279:
0000280:
0000281:
0000282:
0000283:
0000284:
0000285:
0000286:
0000287:
0000288:
0000289:
0000290:
0000291:
0000292:
0000293:
0000294:
0000295:
0000296:
0000297:
0000298:
0000299:
0000300:
0000301:
0000302:
0000303:
0000304:
0000305:
0000306:
0000307:
0000308:
0000309:
0000310:
0000311:
0000312:
0000313:
0000314:
0000315:
0000316:
0000317:
0000318:
0000319:
0000320:
0000321:
0000322:
0000323:
0000324:
0000325:
0000326:
0000327:
0000328:
0000329:
0000330:
0000331:
0000332:
0000333:
0000334:
0000335:
0000336:
0000337:
0000338:
0000339:
0000340:
0000341:
0000342:
0000343:
0000344:
0000345:
0000346:
0000347:
0000348:
0000349:
0000350:
0000351:
0000352:
0000353:
0000354:
0000355:
0000356:
0000357:
0000358:
0000359:
0000360:
0000361:
0000362:
0000363:
0000364:
0000365:
0000366:
0000367:
0000368:
0000369:
0000370:
0000371:
0000372:
0000373:
0000374:
0000375:
0000376:
0000377:
0000378:
0000379:
0000380:
0000381:
0000382:
0000383:
0000384:
0000385:
0000386:
0000387:
0000388:
0000389:
0000390:
0000391:
0000392:
0000393:
0000394:
0000395:
0000396:
0000397:
0000398:
0000399:
0000400:
0000401:
0000402:
0000403:
0000404:
0000405:
0000406:
0000407:
0000408:
0000409:
0000410:
0000411:
0000412:
0000413:
0000414:
0000415:
0000416:
0000417:
0000418:
0000419:
0000420:
0000421:
0000422:
0000423:
0000424:
0000425:
0000426:
0000427:
0000428:
0000429:
0000430:
0000431:
0000432:
Min/Max




















































































































































































































































































































































Min/Max


























































































/*
* Copyright (c), Zeriph Enterprises
* All rights reserved.
*
* Contributor(s):
* Zechariah Perez, omni (at) zeriph (dot) com
*
* THIS SOFTWARE IS PROVIDED BY ZERIPH AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ZERIPH AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if !defined(OMNI_SYSLOG_HPP)
#define OMNI_SYSLOG_HPP
#include <omni/defs/global.hpp>
#include <omni/defs/class_macros.hpp>
#include <omni/strings.hpp>
#include <streambuf>
#if defined(OMNI_OS_WIN)
#else
    #include <syslog.h>
#endif

// TODO: finish this
namespace omni {
    namespace logging {
        class log_level
        {
            public:
                typedef enum enum_t {
                    #if defined(OMNI_OS_WIN)
                        EMERGENCY,
                        ALERT,
                        CRITICAL,
                        ERROR,
                        WARNING,
                        NOTICE,
                        INFO,
                        DEBUG
                    #else
                        EMERGENCY = LOG_EMERG,
                        ALERT = LOG_ALERT,
                        CRITICAL = LOG_CRIT,
                        ERROR = LOG_ERR,
                        WARNING = LOG_WARNING,
                        NOTICE = LOG_NOTICE,
                        INFO = LOG_INFO,
                        DEBUG = LOG_DEBUG
                    #endif
                } enum_t;

                static inline unsigned short COUNT()
                {
                    return 8;
                }

                static inline enum_t DEFAULT_VALUE()
                {
                    return INFO;
                }
                
                static std::string to_string(enum_t v)
                {
                    return _to_val<std::stringstream>(v);
                }
            
                static std::wstring to_wstring(enum_t v)
                {
                    return _to_val<std::wstringstream>(v);
                }

                static enum_t parse(const std::string& val)
                {
                    return _parse(val);
                }

                static enum_t parse(const std::wstring& val)
                {
                    return _parse(val);
                }

                static bool try_parse(const std::string& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::string& val, log_level& out)
                {
                    return _try_parse(val, out);
                }

                static bool try_parse(const std::wstring& val, log_level& out)
                {
                    return _try_parse(val, out);
                }

                static bool is_valid(int32_t val)
                {
                    return _valid(val);
                }
                
                log_level() :
                    OMNI_CTOR_FW(omni::sync::log_level)
                    m_val(DEFAULT_VALUE())
                { }

                log_level(const log_level& cp) :
                    OMNI_CPCTOR_FW(cp)
                    m_val(cp.m_val)
                { }

                log_level(enum_t val) :
                    OMNI_CTOR_FW(omni::sync::log_level)
                    m_val(val)
                { }

                ~log_level()
                {
                    OMNI_TRY_FW
                    OMNI_DTOR_FW
                    OMNI_CATCH_FW
                    OMNI_D5_FW("destroyed");
                }
                
                unsigned short count()
                {
                    return COUNT();
                }
                
                enum_t value() const
                {
                    return this->m_val;
                }

                std::string to_string() const
                {
                    return to_string(this->m_val);
                }

                std::wstring to_wstring() const
                {
                    return to_wstring(this->m_val);
                }

                bool operator!=(const log_level& val) const
                {
                    return !(*this == val);
                }
                
                bool operator!=(enum_t val) const
                {
                    return (this->m_val != val);
                }
                
                log_level& operator=(const log_level& val)
                {
                    if (this != &val) {
                        OMNI_ASSIGN_FW(val)
                        this->m_val = val.m_val;
                    }
                    return *this;
                }

                log_level& operator=(enum_t val)
                {
                    this->m_val = val;
                    return *this;
                }

                log_level& operator=(int32_t val)
                {
                    if (!log_level::is_valid(val)) {
                        OMNI_ERR_RET_FW("Invalid enumeration value specified.", omni::exceptions::invalid_enum(val));
                    } else {
                        this->m_val = static_cast<enum_t>(val);
                    }
                    return *this;
                }

                bool operator<(const log_level& val) const
                {
                    return this->m_val < val.m_val;
                }

                bool operator<(enum_t val) const
                {
                    return this->m_val < val;
                }

                bool operator<(int32_t val) const
                {
                    return this->m_val < static_cast<enum_t>(val);
                }

                bool operator>(const log_level& val) const
                {
                    return this->m_val > val.m_val;
                }

                bool operator>(enum_t val) const
                {
                    return this->m_val > val;
                }

                bool operator>(int32_t val) const
                {
                    return this->m_val > val;
                }

                bool operator==(const log_level& val) const
                {
                    if (this == &val) { return true; }
                    return this->m_val == val.m_val
                            OMNI_EQUAL_FW(val);
                }

                bool operator==(enum_t val) const
                {
                    return this->m_val == val;
                }

                bool operator==(int32_t val) const
                {
                    return this->m_val == val;
                }

                operator enum_t() const
                {
                    return this->m_val;
                }

                operator std::string() const
                {
                    return this->to_string();
                }

                operator std::wstring() const
                {
                    return this->to_wstring();
                }

                OMNI_MEMBERS_FW(omni::system::log_level) // disposing,name,type(),hash()

                OMNI_OSTREAM_FW(omni::system::log_level)
                OMNI_OSTREAM_FN_FW(enum_t)

            private:
                enum_t m_val;

                template < typename S >
                static enum_t _parse(const S& val)
                {
                    enum_t ret;
                    if (_try_parse(val, ret)) { return ret; }
                    OMNI_ERR_FW("invalid enum parse", omni::exceptions::invalid_enum())
                    return DEFAULT_VALUE();
                }

                template < typename S >
                static bool _try_parse(const S& str, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_upper(str), out);
                }

                template < typename S >
                static bool _try_parse(const S& val, log_level& out)
                {
                    enum_t tmp;
                    if (_try_parse(val, tmp)) {
                        out.m_val = tmp;
                        return true;
                    }
                    return false;
                }

                static bool _try_parse(const std::wstring& val, enum_t& out)
                {
                    return _try_parse(omni::string::util::to_string(val), out);
                }

                static bool _try_parse(const std::string& val, enum_t& out)
                {
                    if (!val.empty()) {
                        OMNI_S2E_FW(EMERGENCY)
                        OMNI_S2E_FW(ALERT)
                        OMNI_S2E_FW(CRITICAL)
                        OMNI_S2E_FW(ERROR)
                        OMNI_S2E_FW(WARNING)
                        OMNI_S2E_FW(NOTICE)
                        OMNI_S2E_FW(INFO)
                        OMNI_S2E_FW(DEBUG)
                    }
                    return false;
                }

                template < typename S >
                static std::basic_string< typename S::char_type > _to_val(enum_t v)
                {
                    S ss;
                    switch (v) {
                        OMNI_E2SS_FW(EMERGENCY);
                        OMNI_E2SS_FW(ALERT);
                        OMNI_E2SS_FW(CRITICAL);
                        OMNI_E2SS_FW(ERROR);
                        OMNI_E2SS_FW(WARNING);
                        OMNI_E2SS_FW(NOTICE);
                        OMNI_E2SS_FW(INFO);
                        OMNI_E2SS_FW(DEBUG);
                        default:
                            ss << "UNKNOWN (" << static_cast<int>(v) << ")";
                            break;
                    }
                    return ss.str();
                }

                static bool _valid(int32_t val)
                {
                    return (val ==
                        EMERGENCY ||
                        ALERT ||
                        CRITICAL ||
                        ERROR ||
                        WARNING ||
                        NOTICE ||
                        INFO ||
                        DEBUG
                    );
                }
        };

        /*
            #include <ostream>
#include <streambuf>
#include <string>

#include <syslog.h>

namespace log
{

enum level
{
    emergency = LOG_EMERG,
    alert     = LOG_ALERT,
    critical = LOG_CRIT,
    error     = LOG_ERR,
    warning = LOG_WARNING,
    notice    = LOG_NOTICE,
    info     = LOG_INFO,
    debug     = LOG_DEBUG,
};

enum type
{
    auth = LOG_AUTH,
    cron = LOG_CRON,
    daemon = LOG_DAEMON,
    local0 = LOG_LOCAL0,
    local1 = LOG_LOCAL1,
    local2 = LOG_LOCAL2,
    local3 = LOG_LOCAL3,
    local4 = LOG_LOCAL4,
    local5 = LOG_LOCAL5,
    local6 = LOG_LOCAL6,
    local7 = LOG_LOCAL7,
    print = LOG_LPR,
    mail = LOG_MAIL,
    news = LOG_NEWS,
    user = LOG_USER,
    uucp = LOG_UUCP,
};

}
*/
        
        class syslog : public std::basic_streambuf<char>
        {
            public:
                explicit syslog(const std::string& name, log::type type) :
                    std::basic_streambuf<char>()
                {
                    ::openlog(name.size() ? name.data() : nullptr, LOG_PID, type);
                }
                ~syslog() {
                    ::closelog();
                }

            protected:
                int_type overflow(int_type c = traits_type::eof())
                {
                    if (traits_type::eq_int_type(c, traits_type::eof())) {
                        sync();
                    } else {
                        buffer += traits_type::to_char_type(c);
                    }
                    return c;
                }

                int sync()
                {
                    if (buffer.size()) {
                        ::syslog(level, "%s", buffer.data());
                        buffer.clear();
                        level = ini_level;
                    }
                    return 0;
                }

                void set_level(log::level new_level) noexcept { level = new_level; }

            private:
                static constexpr log::level ini_level = log::info;
                log::level level = ini_level;

                std::string buffer;
        };
    }
}

#endif // OMNI_SYSLOG_HPP