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

PMM-12971 Add pg exporter connection limit #750

Merged
merged 8 commits into from
May 28, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export interface PostgreSQLPayload extends RemoteCommonPayload, TLSCommon {
agent_password: string;
max_query_length: number;
auto_discovery_limit: number;
max_exporter_connections: number;
}

export interface MySQLPayload extends RemoteCommonPayload, TLSCommon {
Expand Down Expand Up @@ -196,6 +197,7 @@ export interface RDSPayload extends CommonRDSAzurePayload {
metrics_mode: string;
qan_postgresql_pgstatements: boolean;
agent_password: string;
max_postgresql_exporter_connections: number;
}

export interface MSAzurePayload extends CommonRDSAzurePayload {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Messages } from './AdditionalOptions.messages';
import { AutoDiscoveryOptionsInterface, TablestatOptionsInterface } from './AdditionalOptions.types';
import {
AutoDiscoveryOptionsInterface,
TablestatOptionsInterface,
MaxConnectionLimitOptionsInterface,
} from './AdditionalOptions.types';

export const tablestatOptions = [
{
Expand Down Expand Up @@ -30,3 +34,14 @@ export const autoDiscoveryOptions = [
label: Messages.form.autoDiscoveryOptions.custom,
},
];

export const maxConnectionLimitOptions = [
{
value: MaxConnectionLimitOptionsInterface.enabled,
label: Messages.form.maxConnectionLimitOptions.enabled,
},
{
value: MaxConnectionLimitOptionsInterface.disabled,
label: Messages.form.maxConnectionLimitOptions.disabled,
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ export const Messages = {
disabled: 'Disabled',
custom: 'Custom',
},
maxConnectionLimitOptions: {
enabled: 'Enabled',
disabled: 'Disabled',
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import { CheckboxField } from 'app/percona/shared/components/Elements/Checkbox';
import { NumberInputField } from 'app/percona/shared/components/Form/NumberInput';
import { RadioButtonGroupField } from 'app/percona/shared/components/Form/RadioButtonGroup';
import { Databases } from 'app/percona/shared/core';
import Validators from 'app/percona/shared/helpers/validators';
import { validators as platformCoreValidators } from 'app/percona/shared/helpers/validatorsForm';

import { rdsTrackingOptions, trackingOptions } from '../FormParts.constants';
import { Messages } from '../FormParts.messages';
import { getStyles } from '../FormParts.styles';
import { AdditionalOptionsFormPartProps, PostgreSQLAdditionalOptionsProps } from '../FormParts.types';

import { autoDiscoveryOptions, tablestatOptions } from './AdditionalOptions.constants';
import { AutoDiscoveryOptionsInterface, TablestatOptionsInterface } from './AdditionalOptions.types';
import { autoDiscoveryOptions, tablestatOptions, maxConnectionLimitOptions } from './AdditionalOptions.constants';
import {
AutoDiscoveryOptionsInterface,
MaxConnectionLimitOptionsInterface,
TablestatOptionsInterface,
} from './AdditionalOptions.types';
import { MongodbTLSCertificate } from './MongodbTLSCertificate';
import { MysqlTLSCertificate } from './MysqlTLSCertificate';
import { PostgreTLSCertificate } from './PostgreTLSCertificate';
Expand Down Expand Up @@ -43,19 +48,36 @@ export const AdditionalOptionsFormPart: FC<AdditionalOptionsFormPartProps> = ({

export const PostgreSQLAdditionalOptions: FC<PostgreSQLAdditionalOptionsProps> = ({ form, isRDS, isAzure }) => {
const selectedOption = form.getState()?.values?.autoDiscoveryOptions;
const maxConnSelectedOption = form.getState()?.values?.maxConnectionLimitOptions;
const [selectedValue, setSelectedValue] = useState<string>(selectedOption || AutoDiscoveryOptionsInterface.enabled);
const [maxConnSelectedValue, setMaxConnSelectedValue] = useState<string>(
maxConnSelectedOption || MaxConnectionLimitOptionsInterface.disabled
);
const styles = useStyles2(getStyles);
const validators = [platformCoreValidators.containsNumber, ...platformCoreValidators.int32];
const validators = [platformCoreValidators.containsNumber, platformCoreValidators.int32];
const maxConnValidators = [Validators.min(0), platformCoreValidators.int32];

const getAutoDiscoveryLimitValue = (type: AutoDiscoveryOptionsInterface) =>
type === AutoDiscoveryOptionsInterface.disabled ? -1 : 10;

const getMaxConnectionLimitValue = (type: MaxConnectionLimitOptionsInterface) =>
type === MaxConnectionLimitOptionsInterface.disabled ? null : 5;

useEffect(() => {
setSelectedValue(selectedOption);
form.change('autoDiscoveryLimit', getAutoDiscoveryLimitValue(selectedOption));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedOption]);

useEffect(() => {
setMaxConnSelectedValue(maxConnSelectedOption);
form.change(
isRDS ? 'maxPostgresqlExporterConnections' : 'maxExporterConnections',
getMaxConnectionLimitValue(maxConnSelectedOption)
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [maxConnSelectedOption]);

return (
<>
<h4>{Messages.form.labels.trackingOptions}</h4>
Expand Down Expand Up @@ -87,6 +109,34 @@ export const PostgreSQLAdditionalOptions: FC<PostgreSQLAdditionalOptionsProps> =
tooltipText={Messages.form.tooltips.postgresqlDetails.autoDiscoveryLimit}
/>
</div>
{!isAzure && (
<div>
<h4>{Messages.form.labels.postgresqlDetails.maxConnection}</h4>
<div className={styles.group}>
<RadioButtonGroupField
name="maxConnectionLimitOptions"
data-testid="max-connection-limit-radio-button-group"
defaultValue={maxConnSelectedValue}
options={maxConnectionLimitOptions}
className={styles.radioField}
label={Messages.form.labels.postgresqlDetails.maxConnectionLimitOptions}
fullWidth
/>
<NumberInputField
key={isRDS ? 'maxPostgresqlExporterConnections' : 'maxExporterConnections'}
name={isRDS ? 'maxPostgresqlExporterConnections' : 'maxExporterConnections'}
defaultValue={5}
placeholder={'5'}
validators={
maxConnSelectedValue === MaxConnectionLimitOptionsInterface.enabled ? maxConnValidators : undefined
}
disabled={maxConnSelectedValue !== MaxConnectionLimitOptionsInterface.enabled}
label={Messages.form.labels.postgresqlDetails.maxConnectionLimit}
tooltipText={Messages.form.tooltips.postgresqlDetails.maxConnectionLimit}
/>
</div>
</div>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ export enum AutoDiscoveryOptionsInterface {
disabled = 'disabled',
custom = 'custom',
}

export enum MaxConnectionLimitOptionsInterface {
enabled = 'enabled',
disabled = 'disabled',
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ export const Messages = {
autoDiscovery: 'Auto-discovery',
autoDiscoveryLimit: 'Auto-discovery limit',
autoDiscoveryLimitOptions: 'State',
maxConnection: 'Maximum connection limit',
maxConnectionLimit: 'Maximum connection limit per PostgreSQL instance',
maxConnectionLimitOptions: 'State',
},
mysqlDetails: {
maxQueryLength: 'Max query length',
Expand Down Expand Up @@ -91,6 +94,7 @@ export const Messages = {
database: 'Database (default: postgres)',
maxQueryLength: 'Max query length',
autoDiscoveryLimit: 'Auto-discovery limit',
maxConnectionLimit: 'Maximum connection limit per PostgreSQL instance',
},
mysqlDetails: {
maxQueryLength: 'Max query length',
Expand Down Expand Up @@ -131,6 +135,8 @@ export const Messages = {
database: 'Database name',
maxQueryLength: 'Full Example (Fingerprint) storage is not allowed by default to have the best performance',
autoDiscoveryLimit: 'Turn off auto-discovery when the total count of databases exceeds the limit.',
maxConnectionLimit:
'The maximum connections the Exporter can open to each PostgreSQL instance for monitoring. Higher values might be needed for larger or busier instances, but avoid setting it too high as it can impact performance. Adjust based on your instance size and monitoring needs.',
},
mysqlDetails: {
maxQueryLength: 'Full Example (Fingerprint) storage is not allowed by default to have the best performance',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('getAdditionalOptions ::', () => {
const fields = container.querySelectorAll('input');
const trakingFields = screen.getAllByTestId('tracking-radio-button');
expect(trakingFields.length).toBe(trackingOptions.length);
expect(fields.length).toBe(12);
expect(fields.length).toBe(16);
});
it('should render correct for RDS PostgreSQL', async () => {
const type = Databases.postgresql;
Expand All @@ -198,6 +198,6 @@ describe('getAdditionalOptions ::', () => {
const fields = container.querySelectorAll('input');
const trakingFields = screen.getAllByTestId('tracking-radio-button');
expect(trakingFields.length).toBe(rdsTrackingOptions.length);
expect(fields.length).toBe(13);
expect(fields.length).toBe(17);
});
});
9 changes: 7 additions & 2 deletions public/app/percona/shared/helpers/validatorsForm/int32.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { INT_32 } from '../../core';

import { lessThan, greaterThan } from '.';
export const int32 = (value: string) => {
const num = parseFloat(value);
if (Number.isFinite(num) && Number.isInteger(num) && num > INT_32.min - 1 && num < INT_32.max + 1) {
return undefined;
}

export const int32 = [greaterThan(INT_32.min - 1), lessThan(INT_32.max + 1)];
return `Must be an Integer number`;
};
Loading