0

This may be a stupid, obvious typing question that I'm just overlooking a simple explanation for, so apologies. While using spdlog, the examples are ALL declared in functions, in my case like this:

void daily_example()
{   auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);  }

This works without complaining about the declaration type. But, I'm writing a device driver, and I need to create a single /var/log/xxx.log rotated daily. So, I need the log instance available outside of any single function or even src file. I've tried inheriting this as class log: public spdlog..., but the compiler informs it is not a class. IN fact, it identifies as a double variable(?). So, the next obvious step would be to move the declaration to being a global:

auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);

And then, when global, the compiler complains that daily_logger's methods can't be used:

error: request for member ‘debug’ in ‘* log’, which is of non-class type ‘double(double) 

So, it can't be used globally. Declared as a double, it complains that the type is still not right. I've seen one example of where this was inherited inside a function, but for some reason the same doesn't appear to work globally. So, I've even tried to just say scr*w it, I'll wrap the whole thing in my OWN class which should be exactly like a function, like this, which also doesn't work:

class log {
    public:
        std::string filename = "/var/log/name-redacted.log";
        log () {
            auto daily_log = spdlog::daily_logger_st("daily_logger", filename, 0, 1 );
        }
};

(same error: error: request for member ‘debug’ in ‘* log’, which is of non-class type ‘double(double) }

This seems like a namespace issue, but since I'm referencing the namespace directly, I can't imagine why it would behave differently. What am I doing wrong here? Also, honestly, I can't imagine a logger where declaring it for use only in a single function is useful. The examples for this seem to completely miss the mark first glance, so I think I'm misunderstanding how its intended to be used in namespaces. Referencing the namespace doesn't seem to work, and using it directly as spdlog::{method}...seems so repetitive globally. But this has to be used across multiple code files, etc.

I've tried:

//Globals
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);

And:

class daily_log: public spdlog {
     public:
          void daily_log () {
               daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
          }
}

And:

class log {
    public:
        std::string filename = "/var/log/name-redacted.log";
        log () {
            auto daily_log = spdlog::daily_logger_st("daily_logger", filename, 0, 1 );
        }
};

Simple full example of what I'm seeing:

// For Logging!
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h"  // support for loading levels from the environment variableinclude "spdlog/fmt/ostr.h" // support for user defined types
#include "spdlog/sinks/daily_file_sink.h"


class log {
    public:
        std::string filename = "/var/log/name-redacted.log";
        log () {
            auto daily_log = spdlog::daily_logger_st("daily_logger", filename, 0, 1 );
        }
};


int main( int argc, char *argv[] )
{
    log.debug("Logging Started.");
}

Gives the output:

$ g++ simple-spdlog.cpp  -o logger -I/usr/include/spdlog -lspdlog
simple-spdlog.cpp: In function ‘int main(int, char**)’:
simple-spdlog.cpp:18:9: error: request for member ‘debug’ in ‘log’, which is of non-class type ‘double(double) throw ()’ {aka ‘double(double)’}
     log.debug("Logging Started.");

  • 1
    `double(double)` type is a function, taking single `double` argument and returning `double`. Sounds like you may have some name conflict with `spdlog` or `daily_logger_mt`, can't reproduce the issue in [Godbolt](https://godbolt.org/z/Ychn6s44a). – Yksisarvinen Mar 27 '23 at 13:45
  • 1
    *While using spdlog, the examples are ALL declared in functions* -- You can make practically anything global and/or static members of a class. You are doing something fundamentally wrong, but it is hard to see what it is with bits and pieces extracted from a larger program. Start with the smallest example, like what @Yksisarvinen posted. – PaulMcKenzie Mar 27 '23 at 13:50
  • I absolutely agree that I doing something fundamentally wrong. I'd say that's a daily occurrence in my case. :) I believe it's something to do with instantiating this within the namespace. Here is a basic example of what I'm doing: – K. Trotman Mar 27 '23 at 14:05
  • Edit your question with any new information (preferably a small example that reproduces the error messages you seem to encounter), don't put it in comments. – Botje Mar 27 '23 at 14:06
  • Hi, I implemented a cookiecutter for cpp and I use splog. I think you could have a look at this: https://github.com/grhawk/cookiecutter-cpp/blob/main/%7B%7Bcookiecutter.project_slug%7D%7D/logging/Log.h ;) – Riccardo Petraglia Mar 27 '23 at 14:09
  • 2
    @K.Trotman [Edit your question](https://stackoverflow.com/posts/75856428/edit) instead of cramming that into a comment. – Botje Mar 27 '23 at 14:10
  • Yes, I saw the same and just edited the question. Sorry. – K. Trotman Mar 27 '23 at 14:13
  • 1
    the code added is unclear. `log->debug("Logging Started.");` Where is the object `log` declared? `log` is a class you defined, and that class has no `debug` method – 463035818_is_not_an_ai Mar 27 '23 at 14:16
  • either something really fishy is going on or the error is not from that code. In your code example `log` is not a `* log`, its also not a `double(double)`, its a class and the line `log->debug("Logging Started.");` would produce a different error message – 463035818_is_not_an_ai Mar 27 '23 at 14:18
  • [This compiles without error](https://godbolt.org/z/aGo4165Gn). Note that I changed the name from `log` to `log_`. One thing is this -- you shouldn't use "common" names when coming up with names for your classes. Names like `log` will cause name clashes, not just here, but what if you call the math `log` function? I've seen similar errors when programmers invent use constants like `FILE`, and at the same time `#include `. – PaulMcKenzie Mar 27 '23 at 14:29
  • Sorry, there was an error in the log use in that from cut/pasting it. It doesn't change the output except that * log is not actually used. The real error is now in the output also without the * log. – K. Trotman Mar 27 '23 at 14:30
  • Riccardo, your use of the spdlog makes a lot more sense to me. I should be able to adapt mine to use that, but it will take a little time. That's exactly what I was trying to do though. – K. Trotman Mar 27 '23 at 14:32
  • @RiccardoPetraglia Looking at your code, [I think you should take a look at this link](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) concerning leading underscores in names. – PaulMcKenzie Mar 27 '23 at 14:35
  • Paul, I agree about the use of log as a variable. I threw that together in 5 minutes as an example. It is interesting to me that it compiles on the web compiler. I am not specifying any particular standard with g++ (see the G++ command in the example), so I think it defaults to C11, and it doesn't compile on that. My g++ is redhat packaged, so I doubt the install is broken. – K. Trotman Mar 27 '23 at 14:39
  • Paul calls the constructor of the custom class. That works. In your code `log.debug("Logging Started.");` makes no sense. There is no `log` object, there is a log class that has no `debug` static method. – 463035818_is_not_an_ai Mar 27 '23 at 14:46
  • Did you want to make the method `static` ? Then you can call it without an instance – 463035818_is_not_an_ai Mar 27 '23 at 14:46
  • @K.Trotman [But as you can see here](https://godbolt.org/z/o6cv6KTje), changing `log_` back to `log` causes a compilation error. That error is due to using `log` as a name that clashes with the math `log` function. That's what led me to suspect a name clash, if you really did call your class `log`. – PaulMcKenzie Mar 27 '23 at 14:59
  • @PaulMcKenzie Thank you for having a look... what is the problem with leading underscores? – Riccardo Petraglia Mar 27 '23 at 15:06
  • 463035818_is_not_a_number, you hit the nail on the head. I forgot the static for this! {duh}. You also mentioned it earlier and I was trying to do a re-write when I saw your second comment. But that's the issue here. When I add that or create an object from the class, it works perfectly. So, it is the way I'm declaring this without the static identifier. – K. Trotman Mar 27 '23 at 15:08
  • @RiccardoPetraglia The link explains this. Leading underscores are reserved for the compiler implementation's usage. What if by chance, a compiler has internally defined those `_LOG...` macros to mean something else? Your code wipes out those definitions. – PaulMcKenzie Mar 27 '23 at 15:09
  • @PaulMcKenzie Sorry, I did not saw the link... :) Would the rest of the code be ok? I am going to fix that! – Riccardo Petraglia Mar 27 '23 at 15:23

0 Answers0