I took a free copyright template code and modified for my own needs but still struggling to make it work. I would appreciate some help to understand.
The problem is that I don't really understand how overloading work especially  with >> operator like in the example below. Why you return the object logger in the friend &operator function. I don't understand how to make void print(); work and interact with friend overloaded operator <<.
This is the example code:
#pragma once
#include <fstream>
namespace  Log{
    class LogFile {
        public:
            enum class logType { LOG_ALWAYS=0, LOG_OKAY, LOG_ERROR, LOG_WARNING, LOG_INFO};
            enum class writeType {FOUT=0, CFOUT, FCOUT, COUT};
            explicit LogFile(string fname = "[nameError]log.txt") : numWarnings(0U), numErrors(0U)
            {
                myFile.open(fname);
                if (myFile.is_open())
                    std::cout << "Log file was created successfully!" << std::endl << std::endl;
                else
                {
                    std::cout << "Fatal Error can't create log file!" << std::endl << "Please check Application permissions" << std::endl;
                    exit(1);
                }
            }
            ~LogFile()
            {
                if (myFile.is_open())
                {
                    myFile << std::endl << std::endl;
                    myFile << numWarnings << " warnings" << std::endl;
                    myFile << numErrors << " errors" << std::endl;
                    myFile.close();
                }
            }
            friend LogFile &operator << (LogFile &logger, const logType e_logtype)
            {
                //TO DO
                //logger.myFile << tm << "|      " << memUsed << "kb added|";
                //<< "000000.000 | 0.0000kb added |"
                switch (e_logtype)
                {
                case LogFile::logType::LOG_ALWAYS:
                    logger.myFile << " ALWAYS| ";
                    break;
                case LogFile::logType::LOG_OKAY:
                    logger.myFile << "   OKAY| ";
                    break;
                case LogFile::logType::LOG_ERROR:
                    logger.myFile << "  ERROR| ";
                    ++logger.numErrors;
                    break;
                case LogFile::logType::LOG_WARNING:
                    logger.myFile << "   WARN| ";
                    ++logger.numWarnings;
                    break;
                default:
                    logger.myFile << "   INFO| ";
                    break;
                }
                return logger;
            }
            friend LogFile &operator << (LogFile &logger, const char* text)
            {
                logger.myFile << tex    t << std::endl;
                return logger;
            }
            LogFile(const LogFile &) = delete;
            LogFile &operator= (const LogFile &) = delete;
            //THIS IS MY PART
            friend void print(LogFile &logger, const char* text, const logType e_logtype, const writeType e_writetype)
            {
                switch (e_writetype)
                {
                case LogFile::writeType::FOUT:
                    logger << LogFile::logType::e_logtype << text;
                    break;
                case LogFile::writeType::FCOUT:
                case LogFile::writeType::CFOUT:
                    std::cout << text << std::endl;
                    logger << LogFile::logType::e_logtype << text;
                    break;
                case LogFile::writeType::COUT:
                default:
                    std::cout << text << std::endl;
                    break;
                }
                return;
            }
        private:
            std::ofstream myFile;
            unsigned int numWarnings;
            unsigned int numErrors;
    };
}
The idea is to use it as a header and in main.cpp log everything by using:
using namespace Log;
LogFile mylog;
mylog.print("Test...", LOG_OKAY, FCOUT);
Where:
LOG_OKAY, LOG_ERROR, etc - types of log info.
COUT, FCOUT, CFOUT, FOUT - log to file or cout or both
Edited: I have solved that problem 3 weeks ago. Thanks to the answer from @zenith. I would post the solution with outlined code I have changed with points to them if the question was openned again. Thanks :)
 
     
    