Skip to content

Commit ad5e341

Browse files
committed
Refine Sentry and logging
1 parent ecbef6e commit ad5e341

File tree

8 files changed

+52
-44
lines changed

8 files changed

+52
-44
lines changed

.eslintrc.js

Lines changed: 0 additions & 24 deletions
This file was deleted.

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default [
2828
argsIgnorePattern: '^_',
2929
varsIgnorePattern: '^_'
3030
}],
31-
'no-console': ['warn', { allow: ['warn', 'error'] }],
31+
'no-console': ['warn', { allow: ['error'] }],
3232
},
3333
},
3434
];

src/server/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ export function createServer(): McpServer {
5151
export async function startServer(server: McpServer): Promise<void> {
5252
const transport = new StdioServerTransport();
5353
await server.connect(transport);
54-
console.error('XcodeBuildMCP Server running on stdio');
54+
log('info', 'XcodeBuildMCP Server running on stdio');
5555
}

src/tools/diagnostic.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const LOG_PREFIX = '[Diagnostic]';
2929
* @param binary The binary name to check
3030
* @returns Object with availability status and optional version string
3131
*/
32-
function checkBinaryAvailability(binary: string): { available: boolean; version?: string } {
32+
export function checkBinaryAvailability(binary: string): { available: boolean; version?: string } {
3333
// First check if the binary exists at all
3434
try {
3535
execSync(`which ${binary}`, { stdio: 'ignore' });
@@ -82,7 +82,7 @@ function checkBinaryAvailability(binary: string): { available: boolean; version?
8282
/**
8383
* Get information about the Xcode installation
8484
*/
85-
function getXcodeInfo():
85+
export function getXcodeInfo():
8686
| { version: string; path: string; selectedXcode: string; xcrunVersion: string }
8787
| { error: string } {
8888
try {
@@ -106,7 +106,7 @@ function getXcodeInfo():
106106
/**
107107
* Get information about the environment variables
108108
*/
109-
function getEnvironmentVariables(): Record<string, string | undefined> {
109+
export function getEnvironmentVariables(): Record<string, string | undefined> {
110110
const relevantVars = [
111111
'XCODEBUILDMCP_DEBUG',
112112
'XCODEMAKE_ENABLED',

src/tools/discover_projects.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ async function _findProjectsRecursive(
128128
if (code === 'EPERM' || code === 'EACCES') {
129129
log('debug', `Permission denied scanning directory: ${currentDirAbs}`);
130130
} else {
131-
log('warn', `Error scanning directory ${currentDirAbs}: ${message} (Code: ${code ?? 'N/A'})`);
131+
log(
132+
'warning',
133+
`Error scanning directory ${currentDirAbs}: ${message} (Code: ${code ?? 'N/A'})`,
134+
);
132135
}
133136
}
134137
}

src/tools/idb.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ async function executeIdbCommand(
7474
log('debug', `${LOG_PREFIX}: Command "${commandName}" exited with code ${code}`);
7575
log('debug', `${LOG_PREFIX}: stdout:\n${stdoutData}`);
7676
if (stderrData) {
77-
log('warn', `${LOG_PREFIX}: stderr:\n${stderrData}`);
77+
log('warning', `${LOG_PREFIX}: stderr:\n${stderrData}`);
7878
}
7979

8080
if (processError) {
@@ -594,7 +594,7 @@ export function registerIdbTools(server: McpServer): void {
594594

595595
// Clean up the temporary file
596596
await fs.unlink(screenshotPath).catch((err) => {
597-
log('warn', `${LOG_PREFIX}/${toolName}: Failed to delete temporary file: ${err}`);
597+
log('warning', `${LOG_PREFIX}/${toolName}: Failed to delete temporary file: ${err}`);
598598
});
599599

600600
// Return the image directly in the tool response

src/utils/logger.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,26 @@
1919

2020
import * as Sentry from '@sentry/node';
2121

22-
const SENTRY_DISABLED = process.env.SENTRY_DISABLED === 'true';
22+
const SENTRY_ENABLED = process.env.SENTRY_DISABLED !== 'true';
23+
24+
if (!SENTRY_ENABLED) {
25+
log('info', 'Sentry disabled due to SENTRY_DISABLED environment variable');
26+
}
2327

2428
/**
2529
* Log a message with the specified level
2630
* @param level The log level (info, warning, error, debug)
2731
* @param message The message to log
28-
* @param context Optional context data to include with error logs sent to Sentry
2932
*/
30-
export function log(level: string, message: string, context?: Record<string, unknown>): void {
33+
export function log(level: string, message: string): void {
3134
const timestamp = new Date().toISOString();
32-
console.error(`[${timestamp}] [${level.toUpperCase()}] ${message}`);
35+
const logMessage = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
3336

34-
// Send error logs to Sentry unless disabled
35-
if (!SENTRY_DISABLED && level.toLowerCase() === 'error') {
36-
Sentry.captureMessage(message, {
37-
level: 'error',
38-
extra: context,
39-
});
37+
if (level === 'error' && SENTRY_ENABLED) {
38+
Sentry.captureMessage(logMessage);
4039
}
40+
41+
// It's important to use console.error here to ensure logs don't interfere with MCP protocol communication
42+
// see https://modelcontextprotocol.io/docs/tools/debugging#server-side-logging
43+
console.error(logMessage);
4144
}

src/utils/sentry.ts

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
import * as Sentry from '@sentry/node';
99
import { version } from '../version.js';
10+
import {
11+
getXcodeInfo,
12+
getEnvironmentVariables,
13+
checkBinaryAvailability,
14+
} from '../tools/diagnostic.js';
1015

1116
Sentry.init({
1217
dsn: 'https://798607831167c7b9fe2f2912f5d3c665@o4509258288332800.ingest.de.sentry.io/4509258293837904',
@@ -27,8 +32,29 @@ Sentry.init({
2732
});
2833

2934
// Add additional context that might be helpful for debugging
30-
Sentry.setTags({
35+
const tags: Record<string, string> = {
3136
nodeVersion: process.version,
3237
platform: process.platform,
3338
arch: process.arch,
34-
});
39+
};
40+
41+
// Only add Xcode Info if it's available
42+
const xcodeInfo = getXcodeInfo();
43+
if ('version' in xcodeInfo) {
44+
tags.xcodeVersion = xcodeInfo.version;
45+
tags.xcrunVersion = xcodeInfo.xcrunVersion;
46+
} else {
47+
tags.xcodeVersion = 'Unknown';
48+
tags.xcrunVersion = 'Unknown';
49+
}
50+
51+
const envVars = getEnvironmentVariables();
52+
tags.env_XCODEBUILDMCP_DEBUG = envVars.XCODEBUILDMCP_DEBUG || 'false';
53+
tags.env_XCODEMAKE_ENABLED = envVars.XCODEMAKE_ENABLED || 'false';
54+
tags.env_XCODEBUILDMCP_RUNNING_UNDER_MISE = envVars.XCODEBUILDMCP_RUNNING_UNDER_MISE || 'false';
55+
56+
const miseAvailable = checkBinaryAvailability('mise');
57+
tags.miseAvailable = miseAvailable.available ? 'true' : 'false';
58+
tags.miseVersion = miseAvailable.version || 'Unknown';
59+
60+
Sentry.setTags(tags);

0 commit comments

Comments
 (0)