A validation error a single user hits once, in the moment, is easy to shrug off. A validation error dozens of users hit every day is a design problem you don't know you have — unless something's writing it down. Displaying an error message on screen and logging that same failure are two completely different jobs: one helps the person filling out the form right now, the other tells you, days later, exactly which field is quietly frustrating everyone.
What you'll learn in this lesson
- Why an on-screen error message alone isn't enough for diagnosing recurring problems
- How to use `\Drupal::logger()` inside `validateForm()` to record a failure
- What information is actually worth logging — and what isn't
- Where to go read those log entries afterward
Why log validation failures at all
An error message that appears once and vanishes the moment the user fixes it and resubmits leaves no trace anywhere. If fifty people a week are all hitting the same validation error on your registration form, you'd genuinely like to know that — it might mean your field's help text is unclear, or the validation rule itself is too strict. A permanent log entry is the only way to notice a pattern across many separate, otherwise-invisible submissions.
Logging from inside validateForm()
namespace Drupal\my_module\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class LoggingForm extends FormBase {
public function getFormId() {
return 'logging_form';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['username'] = [
'#type' => 'textfield',
'#title' => $this->t('Username'),
'#required' => TRUE,
];
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Email'),
'#required' => TRUE,
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$username = $form_state->getValue('username');
if (strlen($username) < 3) {
$form_state->setErrorByName('username', $this->t('Username must be at least 3 characters.'));
\Drupal::logger('my_module')->notice('Validation failed on field "username": value too short (@value).', [
'@value' => $username,
]);
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {}
}
`\Drupal::logger('my_module')` returns a channel-scoped logger — every entry it writes is tagged with your module's name, so you can filter to just your own form's failures later without wading through the whole site's log. Calling `->notice()` writes at a moderate severity level, appropriate for "something worth knowing, not an emergency."
Reading the log entries back
Every entry written via `\Drupal::logger()` lands in Drupal's Database Logging module output, visible to an administrator at /admin/reports/dblog, filterable by type (your module's machine name) and severity. If your site instead ships with syslog logging enabled, the same entries go to your server's system log with the same channel/severity metadata intact — either way, nothing about your `validateForm()` code needs to change.
Quick check: why log inside `validateForm()` specifically, rather than waiting until `submitForm()`? (Answer: `submitForm()` only runs when the form passes validation entirely — a failed submission never reaches it. If you want to know about the failures themselves, not just the successes, the log call has to live inside `validateForm()`, at the exact point the error is set.)
Key takeaways
- An on-screen error message and a log entry serve different audiences — one helps the current user, the other helps you spot recurring problems later.
- `\Drupal::logger('your_module')->notice(...)` writes a channel-scoped entry visible at `/admin/reports/dblog` (or your configured syslog output).
- Log entries only exist if you write them from inside `validateForm()` — `submitForm()` never runs on a failed validation, so it's the wrong place to catch failures.
- Never log sensitive field values (passwords, tokens, payment data) in plain text — log the field name and failure reason instead.
Coming up next
Validation failures are one category of problem — submission failures, where a form passes validation but something goes wrong while actually processing the data, are another. The next lesson covers debugging exactly that: tracing what happens (or doesn't) once `submitForm()` actually runs.