The layout of your logs or your application may dictate a recursive approach.
For instance, say we have these stanzas:
[monitor:///opt/*/logs/access.log*] sourcetype=access [monitor:///opt/.../important.log*] sourcetype=important
The character * will match a single file or directory, while ... will match any depth. This will match the files you want, with the caveat that all of /opt will continually be scanned.
Splunk will continually scan all directories from the first wildcard in a monitor path.
If /opt contains many files and directories, which it almost certainly does, Splunk will use an unfortunate amount of resources scanning all directories for matching files, constantly using memory and CPU. I have seen a single Splunk process watching a large directory structure use 2 gigabytes of memory. A little creativity can take care of this, but it is something to be aware of.
The takeaway is that if you know the possible values for *, you are better off writing multiple stanzas. For instance, assuming our directories in /opt are A and B, the following stanzas will be far more efficient:
[monitor:///opt/A/logs/access.log*] sourcetype=access [monitor:///opt/B/logs/access.log*] sourcetype=access
It is also perfectly acceptable to have stanzas matching files and directories that simply don't exist. This causes no errors, but be careful not to include patterns that are so broad that they match unintended files.