RingDebug.cpp 5.63 KB
Newer Older
Nicolas Jager's avatar
Nicolas Jager committed
1
/***************************************************************************
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * Copyright (C) 2016 by Savoir-faire Linux                                *
 * Author: Jger Nicolas <nicolas.jager@savoirfairelinux.com>              *
 * Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com>          *
 *                                                                         *
 * This program is free software; you can redistribute it and/or modify    *
 * it under the terms of the GNU General Public License as published by    *
 * the Free Software Foundation; either version 3 of the License, or       *
 * (at your option) any later version.                                     *
 *                                                                         *
 * This program is distributed in the hope that it will be useful,         *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 * GNU General Public License for more details.                            *
 *                                                                         *
 * You should have received a copy of the GNU General Public License       *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
 **************************************************************************/
Nicolas Jager's avatar
Nicolas Jager committed
19 20 21 22 23 24 25 26

/* client */
#include "pch.h"

using namespace RingClientUWP;

using namespace Platform;
using namespace Windows::UI::Core;
27
using namespace Windows::Storage;
Nicolas Jager's avatar
Nicolas Jager committed
28

29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
using namespace std::chrono;

std::string
getDebugHeader(std::string file, int line)
{
    auto tid = std::this_thread::get_id();

    seconds s = duration_cast< seconds >(
        system_clock::now().time_since_epoch()
    );
    milliseconds ms = duration_cast< milliseconds >(
        system_clock::now().time_since_epoch()
    );

    static uint64_t secs = s.count();
    static uint64_t millis = ms.count() - (secs * 1000);

46 47 48 49 50
    std::ostringstream out;
    const auto prev_fill = out.fill();
    out << '[' << secs
        << '.' << std::right << std::setw(3) << std::setfill('0') << millis << std::left
        << '|' << std::right << std::setw(5) << std::setfill(' ') << tid << std::left;
51 52 53 54 55 56 57
    out.fill(prev_fill);
    out << "|" << std::setw(32) << (file + ':' + Utils::toString((line.ToString())));
    out << "] ";

    return out.str();
}

Nicolas Jager's avatar
Nicolas Jager committed
58
void
59 60
RingDebug::print(const  std::string& message, const Type& type,
                        std::string file, int line)
Nicolas Jager's avatar
Nicolas Jager committed
61
{
62 63 64
    Utils::runOnWorkerThread([this, message, type, file, line]()
    {
        std::string _message;
Nicolas Jager's avatar
Nicolas Jager committed
65

66 67 68 69
        if (type != Type::DMN)
            _message = getDebugHeader(file, line) + message;
        else
            _message = message;
70

71
        std::wstring wString = std::wstring(_message.begin(), _message.end());
Nicolas Jager's avatar
Nicolas Jager committed
72

73 74
        /* set message type. */
        wString = (type>Type::WNG) ? (L"(EE) ") : ((type>Type::MSG) ? (L"(WW) ") : (L"")) + wString;
Nicolas Jager's avatar
Nicolas Jager committed
75

76 77
        String^ msg;
        msg = ref new String(wString.c_str(), wString.length());
atraczyk's avatar
atraczyk committed
78

79
#if UWP_DBG_VS
80 81
        /* screen it into VS debug console */
        OutputDebugString((wString + L"\n").c_str());
82 83
#endif

84 85 86
#if UWP_DBG_CONSOLE
        /* fire the event. */
        messageToScreen(msg);
87 88 89
#endif

#if UWP_DBG_FILE
90 91
        /* output to file */
        printToLogFile(Utils::toString(msg));
92
#endif
93
    }, WorkItemPriority::Normal);
94 95 96 97 98 99
}

void
RingDebug::print(String^ message, const Type& type,
                        std::string file, int line)
{
100 101 102 103
    Utils::runOnWorkerThread([this, message, type, file, line]()
    {
        /* add header */
        auto messageTimestamped = Utils::toPlatformString(getDebugHeader(file, line)) + message;
104

105 106
        /* set message type. */
        messageTimestamped = (type>Type::WNG) ? ("(EE) ") : ((type>Type::MSG) ? ("(WW) ") : ("")) + messageTimestamped;
Nicolas Jager's avatar
Nicolas Jager committed
107

108
#if UWP_DBG_VS
109 110 111 112
        /* screen it into VS debug console */
        std::wstringstream wStringstream;
        wStringstream << messageTimestamped->Data() << "\n";
        OutputDebugString(wStringstream.str().c_str());
113 114
#endif

115 116 117
#if UWP_DBG_CONSOLE
        /* fire the event. */
        messageToScreen(messageTimestamped);
118
#endif
119

120
#if UWP_DBG_FILE
121 122
        /* output to file */
        printToLogFile(Utils::toString(messageTimestamped));
123
#endif
124
    }, WorkItemPriority::Normal);
125 126
}

127 128
void
RingDebug::print(Exception^ e, std::string file, int line)
129
{
130 131 132 133
    Utils::runOnWorkerThread([this, e, file, line]()
    {
        /* add header */
        auto message = Utils::toPlatformString(getDebugHeader(file, line)) + "Exception : 0x" + e->HResult.ToString() + ": " + e->Message;
134 135

#if UWP_DBG_VS
136 137 138 139
        /* screen it into VS debug console */
        std::wstringstream wStringstream;
        wStringstream << message->Data() << "\n";
        OutputDebugString(wStringstream.str().c_str());
140 141
#endif

142 143 144
#if UWP_DBG_CONSOLE
        /* fire the event. */
        messageToScreen(message);
145 146 147
#endif

#if UWP_DBG_FILE
148 149
        /* output to file */
        printToLogFile(Utils::toString(message));
150
#endif
151
    }, WorkItemPriority::Normal);
152 153
}

154
RingDebug::RingDebug()
155
{
156 157 158 159
    /* clean the log file */
    std::ofstream ofs;
    ofs.open (RingD::instance->getLocalFolder() + "debug.log", std::ofstream::out | std::ofstream::trunc);
    ofs.close();
Nicolas Jager's avatar
Nicolas Jager committed
160
}
161

162 163 164 165 166 167 168 169 170 171 172
void
RingDebug::printToLogFile(std::string msg)
{
    {
        std::lock_guard<std::mutex> l(debugMutex_);
        std::ofstream ofs;
        ofs.open(RingD::instance->getLocalFolder() + "debug.log", std::ofstream::out | std::ofstream::app);
        ofs << msg << "\n";
        ofs.close();
    }
}