-
December 8th, 2020, 08:35 AM
#1
simple log functionality
Hello,
I am supposed to add simple log functonlity.
I googled and used the following class and tested in my local setup
Code:
class Logger
{
public:
// Logger cannot exist without file.
Logger() = delete;
// Disable copy constructor since std::ofstream is not copyable.
Logger(Logger const&) = delete;
// Constructor
explicit Logger(std::string const& f_path)
: log_file{ f_path }
{
if (!log_file.is_open())
{
throw std::runtime_error("Unable to open log file");
}
}
// Disable copy.
Logger& operator=(Logger const&) = delete;
// Cleanup.
~Logger()
{
log_file.close();
}
// Write a single value into log file stream.
template<typename T>
void write(T const& v)
{
log_file << v;
}
// Write multiple values.
template<typename Arg, typename ...Args>
void write(Arg const& arg, Args const&... args)
{
// here we write the first value of the values list.
write(arg);
// here we recursively pass the rest values to the function.
write(args...);
}
private:
// Log file stream.
std::ofstream log_file;
};
But when i run following main its ok
int main(int argc, char* argv[])
{
Logger l{ "test.log" };
l.write(1);
l.write("qwe", 34);
return 0;
}
But, when i wanted to create file, in new path
int main(int argc, char* argv[])
{
Logger l{ "C:\temp\test.log" };
l.write(1);
l.write("qwe", 34);
return 0;
}
its throwing error, that it cannot open the file.
thanks a lot
pdk
-
December 8th, 2020, 08:37 AM
#2
Re: simple log functionality
> Logger l{ "C:\temp\test.log" };
Beware that \ has a special meaning inside strings.
Try
Logger l{ "C:\\temp\\test.log" };
or
Logger l{ "C:/temp/test.log" };
-
December 8th, 2020, 09:15 AM
#3
Re: simple log functionality
Generally logging has additional functionality like logging levels, multiple log outputs (file, console, debug, event viewer, etc), and internal queuing. While you can certainly reinvent all this, you might want to look into existing logging frameworks like nlog or serilog.
-
December 8th, 2020, 09:22 AM
#4
Re: simple log functionality
@salem_c: Thanks a lot, but both options didnot work. Still hits the throw std::runtime_error("Unable to open log file");
Any other ideas
I needed this urgently, so if any help is much appreciated.
-
December 8th, 2020, 09:27 AM
#5
Re: simple log functionality
@Arjay:Im looking for simple text file writting kind of logging
-
December 8th, 2020, 09:52 AM
#6
Re: simple log functionality
Originally Posted by pdk5
@Arjay:Im looking for simple text file writting kind of logging
Yes and as you start adding log statements to your app, you'll wonder why your app performance has dropped. The reason will be that, without queuing, the file writing will quickly become a bottleneck. The stated implementation will also crash if attempting to log from multiple threads.
Writing a logging mechanism is kind of like writing your own string class - it looks easy, but in practice is not.
If you need this urgently why not use something that is already available, such as the frameworks I previously mentioned?
-
December 8th, 2020, 10:03 AM
#7
Re: simple log functionality
Thanks Arjay. i'll check when i want to implement full log functionality. logging is not my responsibility, but i want to create for debug purpose only
-
December 8th, 2020, 10:07 AM
#8
Re: simple log functionality
I'll try to go for simple text file, instead of above:
std:fstream file2("C:/temp/test.log");
But now, how is there anyway to convert the windows style path to above one.. Because the input i get is the absolute windows path : C:\temp\test.log
sorry for basic qs, as i am busy testing my feature, logging is not my work actually
-
December 8th, 2020, 10:08 AM
#9
Re: simple log functionality
Do you check if c:\temp exists?
-
December 8th, 2020, 10:20 AM
#10
Re: simple log functionality
Thanks Arjay, it exists, and
if i do
std:fstream file2("C:/temp/test.log"); test.log gets created.
But if i do
std:fstream file2("C:\temp\test.log"); its not getting created.
So I wanted to create the "windows path ", backslashes to forward slashes... I got the following code
Code:
std::string path = "C:\temp\test.log";
std::replace(path.begin(), path.end(), '\\', '/');
std::ofstream file2(path);
The above replace is not working,,am i gone blind
-
December 8th, 2020, 10:48 AM
#11
Re: simple log functionality
Are you coding for Windows and writing to a fat or ntfs file system? If so, hard coded paths need to be escaped as mentioned in post #2. No need for the hack to convert back slashes to front slashes. Also, what does the std:fstream constructor expect? Does it expect a file to exist? Does it create the file? Does it fail if a file already exists? Google the behavior.
-
December 8th, 2020, 11:02 AM
#12
Re: simple log functionality
Originally Posted by pdk5
Code:
class Logger
{
public:
// Logger cannot exist without file.
Logger() = delete;
// Disable copy constructor since std::ofstream is not copyable.
Logger(Logger const&) = delete;
// Constructor
explicit Logger(std::string const& f_path)
: log_file{ f_path }
{
if (!log_file.is_open())
{
throw std::runtime_error("Unable to open log file");
}
}
...
private:
// Log file stream.
std::ofstream log_file;
};
You check if the file is open. But where do you open it?
Victor Nijegorodov
-
December 8th, 2020, 11:11 AM
#13
Re: simple log functionality
@Arjay: thankyou
std:fstream constructor expect?
I think if the file is not there, it gets created...
not sure why : replace is not working for me
-
December 8th, 2020, 12:34 PM
#14
Re: simple log functionality
Originally Posted by pdk5
@Arjay: thankyou
std:fstream constructor expect?
I think if the file is not there, it gets created...
not sure why : replace is not working for me
Why not just code std:fstream file2("C:\\temp\\test.log");
You need to read up on escape sequences. Your original file name doesn't contain backslashes, it contains tabs, which is why the replace isn't working.
-
December 8th, 2020, 12:41 PM
#15
Re: simple log functionality
@GCDEF: thanks a lot
Sorry for so many q's, but my initial question, was trying to comeup with logger.
But now i just want to try a simple text file. But the issue is, if the input directory path is "forward slash", ofstream creats/opens file propely, even in windows. But in my case, input string is windows format..i.e backslash. i want to convert the file path
std::string filepath= C:/temp
to file std::string filepath=C:\temp
basically, tried to use std::replace is not working... any help is much appreciated
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|