#include <iostream>
#include <Poco/Logger.h>
#include <Poco/PatternFormatter.h>
#include <Poco/FormattingChannel.h>
#include <Poco/ConsoleChannel.h>
#include <Poco/FileChannel.h>
#include <Poco/SplitterChannel.h>
#include <Poco/AutoPtr.h>
#include <Poco/Thread.h>
#include <Poco/Runnable.h>

using namespace Poco;

class LevelFilterFileChannel : public FileChannel
{
public:
    LevelFilterFileChannel() : FileChannel() {}

    void log(const Message& msg) override
    {
        // debug, trace 로그 제외
        if (msg.getPriority() <= Message::PRIO_INFORMATION)
        {
            FileChannel::log(msg);
        }
    }
};

class MyWorker : public Runnable
{
public:
    void run() override
    {
        Logger& logger = Logger::get("aLogger");
        for (int i = 0; i < 5; ++i)
        {
            logger.notice("Poco Thread is running! i = " + std::to_string(i));
            Poco::Thread::sleep(500); // 0.5초 대기
        }
        logger.information("Poco Thread done.");
    }
};

int main()
{
    AutoPtr<ColorConsoleChannel> colorConsoleChannel(new ColorConsoleChannel);
    AutoPtr<LevelFilterFileChannel> fileChannel(new LevelFilterFileChannel);
    fileChannel->setProperty("path", "myapp.log");
    fileChannel->setProperty("rotation", "50000 K"); // 50,000KB 초과시 회전
    fileChannel->setProperty("archive", "timestamp");
    fileChannel->setProperty("purgeAge", "30 days"); // 30일 초과 로그 파일 삭제

    AutoPtr<PatternFormatter> patternFormatter(new PatternFormatter);
    patternFormatter->setProperty(
        "pattern",
        "[%Y-%m-%d %H:%M:%S] [%p] [PID:%P][TID:%T][TH:%I] %t"
    );
    patternFormatter->setProperty("times", "local");
   
    AutoPtr<FormattingChannel> fcConsole(new FormattingChannel(patternFormatter, colorConsoleChannel));  // 콘솔은 모든 로그
    AutoPtr<FormattingChannel> fcFile(new FormattingChannel(patternFormatter, fileChannel));

    // 콘솔 및 파일 채널로 메시지를 전달
    AutoPtr<SplitterChannel> splitter(new SplitterChannel);
    splitter->addChannel(fcConsole);
    splitter->addChannel(fcFile);  

    Logger& logger = Logger::get("Logger");
    logger.setChannel(splitter);
    logger.setLevel(Message::PRIO_TRACE); // 모든 로그 레벨 허용

    logger.fatal("FATAL 메시지");
    logger.critical("CRITICAL 메시지");
    logger.error("ERROR 메시지");
    logger.warning("WARNING 메시지");
    logger.notice("NOTICE 메시지");
    logger.information("INFO 메시지");
    logger.debug("DEBUG 메시지 - 콘솔만");
    logger.trace("TRACE 메시지 - 콘솔만");

    MyWorker worker;
    Thread thread;
    thread.start(worker);

    // 메인 스레드도 로그 남기기
    for (int i = 0; i < 3; ++i)
    {
        logger.notice("Main thread working... i = " + std::to_string(i));
        std::this_thread::sleep_for(std::chrono::milliseconds(400));
    }

    thread.join();
    logger.information("모든 작업 종료");
}

'Language > C++' 카테고리의 다른 글

[C++20] std::span  (0) 2025.05.25
[C++] 함수 const 선언 정리  (0) 2024.09.12

 

  • 함수가 배열 또는 컨테이너(예: std::vector)의 뷰(view) 만을 필요로 할 때.
  • 함수가 읽기 전용 또는 수정 가능한 시퀀스를 받아야 할 때.
  • 함수가 컨테이너의 타입에 독립적이어야 할 때 (std::vector, std::array, C-style 배열 모두 수용).

 

✅ 예제 시나리오: 버퍼를 받아 총합 계산

✅ std::span 사용 버전 (깔끔, 안전, 범용)

#include <iostream>
#include <vector>
#include <array>
#include <span>

int sum(std::span<const int> data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    int c_array[] = {1, 2, 3, 4, 5};

    std::cout << sum(vec) << "\n";      // OK
    std::cout << sum(arr) << "\n";      // OK
    std::cout << sum(c_array) << "\n";  // OK

    return 0;
}

❌ std::span 없이 타입별 오버로드 버전 (지저분하고 유지보수 어려움)

#include <iostream>
#include <vector>
#include <array>

int sum_vector(const std::vector<int>& data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int sum_array(const std::array<int, 5>& data) {
    int total = 0;
    for (int value : data) {
        total += value;
    }
    return total;
}

int sum_c_array(const int* data, size_t size) {
    int total = 0;
    for (size_t i = 0; i < size; ++i) {
        total += data[i];
    }
    return total;
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    int c_array[] = {1, 2, 3, 4, 5};

    std::cout << sum_vector(vec) << "\n";             // OK
    std::cout << sum_array(arr) << "\n";              // OK
    std::cout << sum_c_array(c_array, 5) << "\n";     // OK

    return 0;
}

'Language > C++' 카테고리의 다른 글

[poco] 로그 예제  (0) 2025.07.22
[C++] 함수 const 선언 정리  (0) 2024.09.12

const 선언할 경우 해당 함수의 this는 const가 된다.

즉, 수정 불가능한 상태가 된다. 따라서, this의 모든 멤버 변수에 접근할 수 없다.

또한, 해당 함수에서는 비 const 함수를 호출할 수 없다. 왜냐면 비 const함수에서는 멤버 변수가 수정될 수 있기 때문이다.

class AA {
public:
    AA() = default;
    ~AA() = default;

    void printData(int value) const
    {
        std::cout << this->data;
        this->data = value; // 에러 
        changeData(); // 에러
    }

    void changeData(int value) 
    {
        this->data = value;
    }

private:
    int data = 0;
};
int main()
{
    std::cout << "Hello World!\n";
}

 

 

'Language > C++' 카테고리의 다른 글

[poco] 로그 예제  (0) 2025.07.22
[C++20] std::span  (0) 2025.05.25

+ Recent posts