Is printf in timer callback a good idea?

Is printf in timer callback a good idea?

No.

This could potentially cause a crash if the callback triggered while in the middle of another call to printf.

Even if that wasn’t a risk printf is slow, especially if outputting more than 16 bytes to a serial port. Calling slow functions from within an interrupt is never a good idea if it can be avoided.

If you need some serial output to indicate that a timer has fired for debug reasons then use putc to output a single character. It’s not ideal but far better than using printf.
If you need to output data calculated in the timer then then in the interrupt copy the raw values to a variable and set a flag. In the background loop check for the flag and if set print out the data from the variable.

As AndyA explains, it is not a good idea. You want to get out of an ISR context as soon as possible.

I generally use EventQueue to defer an execution of code. Here is an example.

#include "mbed.h" 

Ticker ticker;
EventQueue *queue = mbed_event_queue(); // event queue
int counter = 0;

void processInUserContext() {
    printf("printing in a user context. counter = %d\r\n", counter);
}

void tickerCallback() {
    counter += 1;
    queue->call(&processInUserContext); // defer the execution to a different context
} 
 
int main() {
    ticker.attach(&tickerCallback, 1.0);       
    queue->dispatch_forever();
}

This page explains the power of EventQueue.

My answers to another topic may be helpful too.