Debugging Pine Script used to be genuinely painful. You could not print a value. Your only options were to plot it and read it off an axis, or draw a label and clutter the chart. Neither told you what happened on a specific bar without a lot of manual work, and neither could show you a message that was not a number.
Pine Script v6, which arrived in November 2024, fixed this with a proper runtime logging system. The log.* functions send timestamped, structured messages to a dedicated Pine Logs pane, so you can trace exactly what your script did, bar by bar, without touching the chart.
The three log functions
There are three, and they differ only in severity level, which lets you filter the log later. Use log.info for ordinary tracing, log.warning for something unusual but survivable, and log.error for a real problem you want to jump out. Each takes a message string, and you build that string the same way you build any Pine string, with str.tostring and str.format.
| Function | Use it for |
|---|---|
| log.info | Normal tracing: values, which branch fired, timing |
| log.warning | Something unusual but not fatal: na where you expected data |
| log.error | A genuine problem you want to stand out in the log |
//@version=6
indicator("Logging basics")
fastMA = ta.sma(close, 10)
slowMA = ta.sma(close, 30)
crossUp = ta.crossover(fastMA, slowMA)
if crossUp
log.info("Cross up on bar {0}: close={1}, fast={2}, slow={3}",
bar_index, close, fastMA, slowMA)
if na(slowMA)
log.warning("slowMA is na at bar {0} (not enough history yet)", bar_index)
plot(fastMA)
plot(slowMA)Open the Pine Logs pane from the editor and you will see each message with the bar's timestamp. The str.format style placeholders keep the calls readable when you are logging several values at once.
A debugging workflow that actually works
The mistake is logging on every bar, which floods the pane and hides the thing you care about. Log conditionally instead. If a signal is not firing when you expect, log inside each part of the condition so you can see which clause is false. If a value looks wrong, log it alongside the inputs that produced it. If you suspect a repainting issue, log barstate.isconfirmed next to the value so you can tell whether you are looking at a confirmed bar or a forming one.
//@version=6
strategy("Why didn't it enter?", overlay = true)
trendUp = close > ta.sma(close, 200)
momentum = ta.rsi(close, 14) > 55
notInTrade = strategy.position_size == 0
// Log only when we are close to entering, to keep the pane readable
if trendUp and momentum
log.info("Setup on bar {0}: trendUp={1}, momentum={2}, flat={3}",
bar_index, trendUp, momentum, notInTrade)
if trendUp and momentum and notInTrade
strategy.entry("Long", strategy.long)This is the logging equivalent of a breakpoint. Instead of guessing why the strategy skipped a trade, you see the exact bar and the exact state of each condition. It pairs especially well with debugging compile-clean scripts that behave wrong at runtime, which is a different problem from code that will not compile at all, covered in Pine Script won't compile.
What logging does not do
Logs are for your own debugging in the editor. They are not a way to send data out of TradingView, and they do not persist as a data feed you can consume elsewhere. If you want your script to trigger action outside the platform, that is the alerts and webhook path, which is a separate mechanism described in building a repaint-free alert system and can Pine Script connect to an API. Keep the two ideas separate: logs are for you, alerts are for the outside world.
Logging plus a tool that catches errors early
Runtime logging is the right tool once your code compiles and you are chasing a behavioral bug. A lot of the time, though, the problem is earlier: the code does not compile, or it uses outdated syntax, and no amount of logging helps until that is fixed. That earlier stage is where a specialized tool saves the most time.
PineScripter generates v6 code that compiles and reads TradingView's errors to fix them automatically, so you spend your debugging energy on strategy logic rather than syntax. Once you are at the logic stage, log.info becomes your best friend. If you want to skip straight to working code you can then instrument with logs, try PineScripter free.
Disclaimer: PineScripter is a coding tool for Pine Script development. It does not provide financial advice and does not guarantee trading profits. Always backtest strategies thoroughly and understand the risks before live trading.