PHP syslog() Function: Everything You Need to Know
As a PHP developer, you may need to log system messages for debugging and troubleshooting purposes. The syslog() function is a built-in function in PHP that
The syslog() function sends a message to the system logger — the same logging facility used by the operating system and other services (the destination is /var/log/syslog or /var/log/messages on most Linux systems, the Console / unified log on macOS, and the Event Log on Windows). Unlike writing to a file with error_log() or file_put_contents(), syslog() hands your message to a daemon that can route, filter, rotate, and forward it for you. This page covers the syntax, the priority and facility constants, a complete working example, and the gotchas worth knowing.
Syntax
syslog(int $priority, string $message): boolThe function takes two parameters and returns true on success or false on failure:
$priority— the severity level of the message, expressed as one of theLOG_*priority constants below.$message— the text to log. The two-character sequence%mis replaced by the error message string of the currenterrno(the system's last error), which is occasionally useful but means literal percent signs should be escaped as%%.
Priority levels
The priority tells the logger how severe the message is. From most to least urgent:
| Constant | Meaning |
|---|---|
LOG_EMERG | System is unusable |
LOG_ALERT | Action must be taken immediately |
LOG_CRIT | Critical condition |
LOG_ERR | Error condition |
LOG_WARNING | Warning condition |
LOG_NOTICE | Normal but significant condition |
LOG_INFO | Informational message |
LOG_DEBUG | Debug-level message |
The logger's own configuration decides which priorities actually get written, so a LOG_DEBUG line may be discarded while a LOG_ERR line is kept — your code still calls syslog() the same way regardless.
A complete example
You don't strictly need openlog() — calling syslog() on its own works — but opening the connection first lets you set an identifying prefix and a facility so your messages are easy to find and route.
<?php
// Open a connection: tag every line with "myapp", include the PID,
// and also echo to stderr. LOG_USER is the generic application facility.
openlog("myapp", LOG_PID | LOG_PERROR, LOG_USER);
syslog(LOG_INFO, "User #42 logged in");
syslog(LOG_WARNING, "Disk usage above 80%%"); // %% = a literal percent sign
syslog(LOG_ERR, "Payment gateway timed out");
closelog();A resulting line in the system log looks roughly like this:
Jun 21 14:03:11 host myapp[3187]: Payment gateway timed outopenlog() accepts three arguments: an identifier prefixed to each message, a bitmask of options (LOG_PID adds the process ID, LOG_PERROR also prints to stderr, LOG_CONS falls back to the console if the logger is unreachable), and a facility that categorizes the source. Common facilities are LOG_USER (the default for generic apps), LOG_LOCAL0–LOG_LOCAL7 (reserved for your own custom routing), LOG_DAEMON, and LOG_MAIL. closelog() closes the connection — optional, but tidy.
When should I use it?
- Long-running services and CLI workers where there's no browser to show errors and you want logs to land in the same place as the rest of the system's logs.
- Centralized logging — a syslog daemon can forward messages to a remote collector (rsyslog, journald, an ELK/Graylog stack), so you get aggregation for free.
- Severity-based routing — pick the facility/priority and let the daemon decide what to store, alert on, or drop.
For ordinary per-application error logging that just writes to a file, error_log() is usually simpler. Reach for syslog() when you want the message to enter the OS-level logging pipeline.
Common gotchas
- Escape literal percent signs.
syslog()interprets%m; an unescaped%in your message can produce surprising output. Write%%for a literal percent. - Messages can be silently dropped. If the logger's configuration filters out your priority/facility, nothing appears — that is configuration, not a PHP error. Check
/etc/rsyslog.conforjournalctlif a line goes missing. - It is not the same as PHP's
error_logini setting. Settingerror_log = sysloginphp.iniroutes PHP's internal errors to syslog; callingsyslog()yourself logs your own messages and is independent of that setting. - One newline per call. Pass a single line; the daemon adds the timestamp, host, and tag. Don't embed
\nin the message.
Related functions
openlog()— open the connection and set the identifier and facility.closelog()— close the syslog connection.error_log()— send a message to a file, email, or the configured log.
Conclusion
syslog() is the PHP entry point into the operating system's logging pipeline. Choose a meaningful priority, optionally open a connection with openlog() to add an identifier and facility, escape literal percent signs, and remember that the daemon — not PHP — decides what is ultimately stored. For simple file logging, prefer error_log(); for OS-level, routable, centralizable logs, syslog() is the right tool.