Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: per account imap and smtp debugging #10301

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

SebastianKrupinski
Copy link
Contributor

@SebastianKrupinski SebastianKrupinski commented Oct 28, 2024

At the moment there is no ability to debug a single mail account.

This adds the ability to enable debugging from the command line using a occ command on a single account and protocol. This also creates a separate file for each account that is enable instead of logging all accounts to the same log file. ( {data directory}/mail-{user id}-{account id}-imap.log )

// command arguments and options
mail:account:debug [--imap] [--imap-full] [--smtp]

// enable debugging for imap
mail:account:debug 14 --imap

// enable debugging for imap with message contents
mail:account:debug 14 --imap-full

// enable debugging for smtp
mail:account:debug 14 --smtp

// enable debugging for imap and smtp
mail:account:debug 14 --imap --smtp

// disable debugging
mail:account:debug 14

// enable for single run with environmental variable
NC_MAIL_DEBUG=imap php occ mail:account:sync 14

@SebastianKrupinski SebastianKrupinski self-assigned this Oct 28, 2024
@SebastianKrupinski SebastianKrupinski force-pushed the enh/add-occ-debug-command branch 2 times, most recently from 0e8d1a5 to 22ba6c1 Compare October 28, 2024 23:49
@SebastianKrupinski SebastianKrupinski marked this pull request as draft October 28, 2024 23:58
@SebastianKrupinski
Copy link
Contributor Author

TODO: Fix integration test

@SebastianKrupinski SebastianKrupinski marked this pull request as ready for review October 29, 2024 00:32
@SebastianKrupinski
Copy link
Contributor Author

TODO: Fix integration test

Done

@SebastianKrupinski SebastianKrupinski force-pushed the enh/add-occ-debug-command branch from 77998a6 to 421a8dc Compare October 29, 2024 14:40
Comment on lines 43 to 44
private int $debugDefault = 1 << 0; // 1 (0000 0001)
private int $debugFull = 1 << 1; // 2 (0000 0010)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please not bit-shift integers here. This is very hard to understand and this ain't C or a high frequency trading application.

I think it is fine to use an associative array here and serialize it to JSON.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I've removed the bit shifting, we can still just use a regular integer and do a bit comparison.

Copy link
Member

@st3iny st3iny Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant both. I don't like having a compressed int as a field. That makes it hard to understand when encountered outside of the code, e.g. in a database dump.

As this is not performance critical code I would prefer another way, e.g. a serialized JSON string or concatenated string ("imap|smtp") or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I've changed it to a concatenated string, although I think int would have cleaner.

Copy link
Member

@st3iny st3iny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the comment above.

Copy link
Member

@st3iny st3iny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I posted a reply in the thread above.

I meant both. I don't like having a compressed int as a field. That makes it hard to understand when encountered outside of the code, e.g. in a database dump.

As this is not performance critical code I would prefer another way, e.g. a serialized JSON string or concatenated string ("imap|smtp") or similar.

@kesselb
Copy link
Contributor

kesselb commented Nov 5, 2024

Please change "4.1.0-alpha.2" to "4.1.0-alpha.3" in info.xml to trigger the migration.

@kesselb
Copy link
Contributor

kesselb commented Nov 5, 2024

Please change "4.1.0-alpha.2" to "4.1.0-alpha.3" in info.xml to trigger the migration.

You may want to wait until #10326 is merged and bump after a rebase.

@SebastianKrupinski
Copy link
Contributor Author

Please change "4.1.0-alpha.2" to "4.1.0-alpha.3" in info.xml to trigger the migration.

You may want to wait until #10326 is merged and bump after a rebase.

Done. I've changed the version to '4.2.0-alpha.1' that way it will migrate properly after the '4.2.0-alpha.0' release.

Copy link
Member

@ChristophWurst ChristophWurst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm missing now is a way to enable Mail debug mode for one occ run.

Before I could do php NC_debug=1 occ mail:account:sync .... This allowed running one sync in debug mode and leave the rest (of production) untouched. Now I have to globally set the account for debug and it will influence production, e.g. through background jobs or when the user has the app open in the browser.

Any idea how we can bring the old trick back?

@SebastianKrupinski
Copy link
Contributor Author

What I'm missing now is a way to enable Mail debug mode for one occ run.

Before I could do php NC_debug=1 occ mail:account:sync .... This allowed running one sync in debug mode and leave the rest (of production) untouched. Now I have to globally set the account for debug and it will influence production, e.g. through background jobs or when the user has the app open in the browser.

Any idea how we can bring the old trick back?

So you want to use a single use environmental variable to enable debugging, no problem.

NC_MAIL_DEBUG=imap php occ mail:account:sync 14

@kesselb
Copy link
Contributor

kesselb commented Nov 7, 2024

I’d like to suggest removing the option to enable debugging separately for each protocol (like IMAP or SMTP). This would make the setup simpler, with just one debug option instead. I think enabling debugging for individual protocols adds extra complexity without much benefit.

@@ -184,7 +184,7 @@ jobs:
run: echo "SELECT * FROM mysql.slow_log WHERE sql_text LIKE '%oc_mail%' AND sql_text NOT LIKE '%information_schema%'" | mysql -h 127.0.0.1 -u root -pmy-secret-pw
- name: Print debug logs
if: ${{ always() }}
run: cat nextcloud/data/horde_*.log
run: cat nextcloud/data/mail-*-*-imap.log
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
run: cat nextcloud/data/mail-*-*-imap.log
run: cat nextcloud/data/mail*.log

To also print smtp and sieve like before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would kind of defeat the purpose of per account logging, as all account smtp transmissions would end up in the same file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NVM. I miss understood this, sure I can change this.

protected const ARGUMENT_ACCOUNT_ID = 'account-id';
protected const OPTION_IMAP_DEFAULT = 'imap';
protected const OPTION_IMAP_FULL = 'imap-full';
protected const OPTION_SMTP_DEFAULT = 'smtp';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about Sieve? ;)

It's using the SieveClientFactory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the SieveClientFactory, it will need to be refactored first, so I thought it would be best to add sieve in a separate PR.

@@ -117,8 +117,16 @@ public function getClient(Account $account, bool $useCache = true): Horde_Imap_C
'backend' => $this->hordeCacheFactory->newCache($account),
];
}
if ($this->config->getSystemValue('debug', false)) {
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/horde_imap.log';
$debug = array_merge(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to keep the protocol option, then this code should go into a small service or into the account object.

classDiagram
    class DebugHelper
    DebugHelper : +debugImap(account) bool
    DebugHelper : +debugSmtp(account) bool
    DebugHelper : +debugSieve(account) bool
    DebugHelper : +fileNameImap(account) string
    DebugHelper : +fileNameSmtp(account) string
    DebugHelper : +fileNameSieve(account) string
Loading

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that can be done. Let see what the rest think.

if ($this->config->getSystemValue('debug', false)) {
$params['debug'] = $this->config->getSystemValue('datadirectory') . '/horde_imap.log';
$debug = array_merge(
explode('|', $this->config->getSystemValueString('MAIL_DEBUG')),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware that getSystemValueString is used here as a workaround for reading environment variables, but I have some concerns:

  • Although we don't have strict conventions for naming configuration variables, all variables in config.sample.php use lowercase. I’d prefer to keep this consistent.
  • For configuration options related to SMTP in config.sample.php, we currently use the mail_ prefix. While smtp_ might be more accurate, it’s not feasible to change this now 😞
  • Our standard format is usually app.mail.xyz, but this could be problematic when working with NC_ environment variables due to naming restrictions in Linux (see allowed characters in Linux environment variable names).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • 1 sure I can change it to lower case

  • 2 yes I could make it support mail_ and smtp_ or anything else and this would enable global debugging, but the idea behind this PR, is to NOT touch the config file at all for mail communication issues, also to NOT enable debugging for all user(s) mail account(s) at the same time and to separate the transmission logs so that its easier and faster to find issues. Just imagine if you have a system with 100 mail accounts and only 2 accounts have an intermittent problem a few times a day.
    yes I know that by adding the 'getSystemValueString' you can now set the debugging in the config.php, but the purpose was for one time environmental variables.

  • 3 yes that is why it has to stay with an under sore, the only other option is one word

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For configuration options related to SMTP in config.sample.php, we currently use the mail_ prefix. While smtp_ might be more accurate, it’s not feasible to change this now 😞

I was referring to the symfony mailer configuration in Nextcloud using mail_ as prefix and thus consider mail_debug not an ideal choice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I know that by adding the 'getSystemValueString' you can now set the debugging in the config.php, but the purpose was for one time environmental variables.

In a previous version, you were using $_ENV / getenv, why did you withdraw this approach? I think that would be cleaner than hijacking SystemConfig 🏴‍☠️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was referring to the symfony mailer configuration in Nextcloud using mail_ as prefix and thus consider mail_debug not an ideal choice.

Ah, Okay, yeah we can still change it to mail_app_debug or anything else.

In a previous version, you were using $_ENV / getenv, why did you withdraw this approach? I think that would be cleaner than hijacking SystemConfig 🏴‍☠️

I agree it was cleaner but abandoned the approach, ironically because I thought it would get flagged during the review process, for one of two reasons,

  • A. Because I was overriding account data in the MailAccount class with information from a different source. Didn't think this was best practice.
  • B. Because I was using raw system values

@SebastianKrupinski
Copy link
Contributor Author

I’d like to suggest removing the option to enable debugging separately for each protocol (like IMAP or SMTP). This would make the setup simpler, with just one debug option instead. I think enabling debugging for individual protocols adds extra complexity without much benefit.

Well the logic is that you only diagnose issues in one protocol at a time anyway, so there was no point in logging protocols you are not interested in. Lets see what @ChristophWurst and @st3iny think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗️ In progress
Development

Successfully merging this pull request may close these issues.

4 participants