s-fleck / lgrExtra

Extra Appenders for the lgr Package
https://s-fleck.github.io/lgrExtra/
Other
7 stars 2 forks source link

Error in sprintf(message, ...) : too few arguments when try to log to database #6

Open MislavSag opened 1 year ago

MislavSag commented 1 year ago

I have tried to start logging to database:

lg <- get_logger("db_logger")
lg$
  set_propagate(FALSE)$
  add_appender(
    name = "db", 
    lgrExtra::AppenderDbi$new(
      conn = dbConnect(RPostgres::Postgres(),
                      dbname = "defaultdb",
                      host = "xxxxdb.ondigitalocean.com",
                      port = 25060L,
                      user = "doadmin",
                      password = "xxx"
      ),
      table = "log",
      buffer_size = 2L
    )
  )

but I get an error:

Error in sprintf(message, ...) : too few arguments
MislavSag commented 1 year ago

I have tried with MySQL database but got the same error:

lg <- get_logger("db_logger")
lg$
  set_propagate(FALSE)$
  add_appender(
    name = "db",
    lgrExtra::AppenderDbi$new(
      conn = dbConnect(RMariaDB::MariaDB(),
                       dbname = "defaultdb",
                       host = "xxxx0.b.db.ondigitalocean.com",
                       port = 25060L,
                       user = "doadmin",
                       password = "xxx"
      ),
      table = "logg"
    )
  )
s-fleck commented 1 year ago

do you get ther error when initializing the table, or when trying to log something? (e.g. lg$fatal("error happaned"))

and can you maybe post the traceback() here?

edit: I am fairly certain there is a deeper problem at play here that is masked by a second error in the function that constructs the error message, so I need the traceback for further analysis :(

MislavSag commented 1 year ago

I don't have the table. Actually the database is empty (not tables at all). When I looked at the function, it seems the function creates the table if it doesn't already exists. Here is the traceback:

12: sprintf(message, ...)
11: structure(class = c(class, "error", "condition"), list(message = as.character(message), 
        call = call, ...))
10: errorCondition(message = sprintf(message, ...), call = NULL, 
        class = "AppenderConfigDoesNotMatchDbTableError")
9: AppenderConfigDoesNotMatchDbTableError("table `%s` does not exist and no col_types were specified in `layout`")
8: lapply(list(...), as.character)
7: .makeMessage(..., domain = domain)
6: stop(AppenderConfigDoesNotMatchDbTableError("table `%s` does not exist and no col_types were specified in `layout`"), 
       self$table_name)
5: initialize(...)
4: lgrExtra::AppenderDbi$new(conn = dbConnect(RPostgres::Postgres(), 
       dbname = "defaultdb", host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com", 
       port = 25060L, user = "doadmin", password = "xxx"), 
       table = "logg")
3: inherits(appender, "Appender")
2: assert(inherits(appender, "Appender"))
1: lg$set_propagate(FALSE)$add_appender(name = "db", lgrExtra::AppenderDbi$new(conn = dbConnect(RPostgres::Postgres(), 
       dbname = "defaultdb", host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com", 
       port = 25060L, user = "doadmin", password = "xxx"), 
       table = "logg"))
s-fleck commented 1 year ago

hmm it seems something is wrong with the layout... With the latest lgrExtra version from github you should now at least get the correct error message... . I can't debug it now because i'll set up a db but i'll look into it when I get around to it.

can you try setting the layout explicitly:

app <- AppenderDbi$new(
    conn = dbConnect(RMariaDB::MariaDB(),
                       dbname = "defaultdb",
                       host = "xxxx0.b.db.ondigitalocean.com",
                       port = 25060L,
                       user = "doadmin",
                       password = "xxx"
   ),
  layout = lgrExtra::LayoutMySql$new()
)

(or LayoutPostgres for postgress)

If that doesn't work, it should be possible to create the target log table manually first, with column types like this:

    level = "integer",
    timestamp = "timestamp",
    logger = "varchar(256)",
    caller = "varchar(256)",
    msg = "varchar(2048)"

(creating the table manually is kinda "nicer" anyways IMHO, but i still have to look into why it doesnt work)

MislavSag commented 1 year ago

for this part :

app <- AppenderDbi$new(
    conn = dbConnect(RMariaDB::MariaDB(),
                       dbname = "defaultdb",
                       host = "xxxx0.b.db.ondigitalocean.com",
                       port = 25060L,
                       user = "doadmin",
                       password = "xxx"
   ),
  layout = lgrExtra::LayoutMySql$new()
)

it says:

Error in inherits(table, "Id") : 
  argument "table" is missing, with no default

so I tried:

app <- AppenderDbi$new(
  conn = dbConnect(RPostgres::Postgres(),
                   dbname = "defaultdb",
                   host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com",
                   port = 25060L,
                   user = "doadmin",
                   password = "AVNS_5qn9VrZkXntvZnQNsSm"
  ),
  layout = lgrExtra::LayoutPostgres$new(),
  table = "logtbl"
)

I got the same error:

Error in sprintf(message, ...) : too few arguments

Then, I have created the table myself:

connec <- dbConnect(RPostgres::Postgres(),
                    dbname = "defaultdb",
                    host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com",
                    port = 25060L,
                    user = "doadmin",
                    password = "xxx"
)
df = data.frame(
  level = integer(0),
  timestamp = POSIXct(0),
  logger = character(0),
  caller = character(0),
  msg = character(0)
)
str(df)
dbDataType(RPostgres::Postgres(), df)
dbWriteTable(connec, "logtbl", value = df, overwrite = TRUE, append = FALSE, row.names = FALSE)
dbListTables(connec)
dbDisconnect(connec)

then, this code works:

lg <- get_logger("db_logger")
lg$
  set_propagate(FALSE)$
  add_appender(
    name = "db",
    lgrExtra::AppenderDbi$new(
      conn = dbConnect(RPostgres::Postgres(),
                       dbname = "defaultdb",
                       host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com",
                       port = 25060L,
                       user = "doadmin",
                       password = "AVNS_5qn9VrZkXntvZnQNsSm"
      ),
      table = "logtbl"
    )
  )

lg$info("Logging to databases uses a buffer")
lg$info("As the buffer size is 2, no insert took place till now")
lg$appenders$db$show()

lg$info("Now as the buffer is rotated, all events are output to the db")
lg$appenders$db$show()

and I can see data in my table afterwords:

connec <- dbConnect(RPostgres::Postgres(),
                    dbname = "defaultdb",
                    host = "db-postgresql-fra1-02794-do-user-8031900-0.b.db.ondigitalocean.com",
                    port = 25060L,
                    user = "doadmin",
                    password = "xxx"
)
dbReadTable(connec, "logtbl")
dbDisconnect(connec)

EDIT: Datatypes from df object above are:

        level     timestamp        logger        caller           msg 
    "INTEGER" "TIMESTAMPTZ"        "TEXT"        "TEXT"        "TEXT" 
s-fleck commented 1 year ago

Ok glad that the workaround works.

I hope I get around fixing the problem soon, all this DB stuff is sadly a bit complicated to debug.

Nevertheless i generally recommended to generate the target tables manually anyways.

MislavSag commented 1 year ago

Agree it is better to crate db manually.

Thanks!

s-fleck commented 1 year ago

So it seems I intentionally disabled automatic creation of log tables for most databases (except sqlite). I have to think weather I should keep it that way, or provide some meaningful defaults i guess...

If it's no hassle, could you provide me the datatypes you are using for either postgres or mariadb as inspiration? (whatever you ended up using)