How do I print line breaks and HTML in a watchdog message? I am trying to log emails to watchdog for testing in my local dev environment.

function MYMODULE_mail_alter(&amp;$message) {
  // First: Prevent the mail from being sent.
  $message['send'] = FALSE;

  // Next: Log the mail so it can be debugged if necessary
  ksm($message);
  $logemail = $message['subject'] .'\nThe following email was not sent: \n&lt;pre&gt;Subject:&lt;br&gt;' . $message['subject'] . '&lt;br&gt;Body:&lt;br&gt;'  . $message['body'][0] . '&lt;/pre&gt;';
  watchdog('MYMODULE', '@logemail', array('@logemail' =&gt; $logemail), WATCHDOG_ALERT);
}


However, this gives me a value for Message that doesn't have any line breaks and ignores my HTML &lt;br&gt; and \n:

Patrick K, new members for the week of April 23\nThe following email was not sent: \n&lt;pre&gt;Subject:&lt;br&gt;Patrick K, new members for the week of April 23&lt;br&gt;Body:&lt;br&gt;&lt;p&gt;Dear Patrick K,&lt;/p&gt; &lt;p&gt;We haven't seen you in awhile. Hundreds of people have joined since you last logged in.&lt;/p&gt; &lt;p&gt;&lt;a href=""&gt;Log in now and say hello to our newest members!&lt;/a&gt;&lt;/p&gt;&lt;/pre&gt;


How can I get the line breaks and HTML to be rendered in the watchdog message?
However, this gives me a value for Message that doesn't have any line breaks and ignores my HTML &lt;br&gt; and \n


As well it should :)

You've wrapped the HTML message in a &lt;pre&gt; tag, whose job is simply to preserve everything within as literal text, so that the browser won't interpret it as HTML. To fix, just remove the &lt;pre&gt; tags. If there's a possibility the email content could have been user-submitted, run it through filter_xss() first with an appropriate list of permitted tags, to avoid pain when you view the log message.

At the same time, \n isn't an escape char in HTML, so that's treated literally and rendered as text. It's an escape char in PHP, but it won't affect the outcome here as browsers collapse multiple whitespace chars into a single space anyway.

You could use PHP's nl2br to convert \n to &lt;br&gt; automatically if the message content was dynamic, but since you're using a literal string, you might as well just be explicit and use &lt;br&gt; instead of \n when you want a line break.

This is a basic working example:

$message = [
  'subject' =&gt; 'test subject',
  'body' =&gt; ['&lt;div class="test"&gt;some content&lt;br /&gt;On a new line&lt;/div&gt;'],
];

$allowed_tags = array('div', 'a', 'table', 'br', 'etc...');
$output = '!subject &lt;br /&gt;The following email was not sent: &lt;br /&gt;Subject:&lt;br /&gt;!subject&lt;br /&gt;Body:&lt;br /&gt;!body';
$args = array('!subject' =&gt; filter_xss($message['subject'], $allowed_tags), '!body' =&gt; filter_xss($message['body'][0], $allowed_tags));
watchdog('MYMODULE', $output, $args, WATCHDOG_ALERT);


It's worth noting that the list view of the watchdog messages strips out HTML, so without the spaces after the first !subject and not sent:, some of the message will run together and make it harder to read at a glance.