Sentry๋Š” ์˜ค๋ฅ˜ ๋˜๋Š” ์˜ˆ์™ธ๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๋กœ ํšŒ์‚ฌ์—์„œ ์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๋Š” ์–ธ์–ด์ธ ์ž๋ฐ”, ํŒŒ์ด์ฌ, Vue ๋“ฑ ๋‹ค์–‘ํ•œ ์–ธ์–ด ํ”Œ๋žซํผ๊ณผ์˜ ์—ฐ๋™์„ ์ง€์›ํ•œ๋‹ค. Sentry๋ฅผ ๋„์ž…ํ•˜๊ฒŒ ๋˜๋Š” ์ด์œ ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š๊ณ  QA ์—”์ง€๋‹ˆ์–ด๊ฐ€ ํ…Œ์ŠคํŠธํ•˜๋Š” ๊ณผ์ • ํ˜น์€ ๊ณ ๊ฐ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๋งˆ์ง€๋ง‰์œผ๋กœ ๊ฒ€์ˆ˜ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋ฐœ๊ฒฌ๋˜์ง€ ์•Š์€ ์ทจ์•ฝ์ ์„ ์•Œ์•„์ฑ„๊ธฐ ์œ„ํ•จ์ด๋‹ค. ๊ทธ๋™์•ˆ ๊ฒฝํ—˜ํ–ˆ๋˜ ๋Œ€๋ถ€๋ถ„์˜ ํ’ˆ์งˆ ์ด์Šˆ๋Š” ๋ช…ํ™•ํ•˜์ง€ ์•Š์€ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ๋ถ€์กฑํ•œ ๋ฆฌ๋ทฐ ๊ณผ์ •์œผ๋กœ ์ธํ•ด์„œ ์ธํ”„๋ผ ๊ตฌ์„ฑ๊ณผ ์‚ฌ์šฉ์ž์˜ ๋™์ž‘์— ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์ด ๋Œ€๋ถ€๋ถ„์ด์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

์‹œ์Šคํ…œ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์˜ˆ์ธกํ•˜๋Š” ๊ธฐ๋Šฅ์˜ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ํŒŒ์ด์ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‹ด๋‹นํ•˜๋Š” ํŒ€์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ Sentry๋ฅผ ๋„์ž…ํ•˜์ง„ ์•Š๊ณ  ์žˆ๋‹ค.

Self-Hosted Sentry

Self-Hosted Sentry์—์„œ ์ œ๊ณตํ•˜๋Š” ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ On-Premise ํ™˜๊ฒฝ์—์„œ Sentry๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•˜์˜€๋‹ค. ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ์™€ ๋„์ปค ์ปดํฌ์ฆˆ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹คํ–‰ ์ž์ฒด๋Š” ๊ฐ„๋‹จํ•œ๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ตฌ๋™๋˜๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค. ์ธํ”„๋ผ ๋น„์šฉ์„ ์•„๋ผ๊ณ ์ž ๋ฆฌ์†Œ์Šค ์ž์› ์‚ฌ์šฉ๋ฅ ์ด ์ €์กฐํ•œ ์ธ์Šคํ„ด์Šค์— ์‹คํ–‰ํ•œ ์ƒํƒœ์ธ๋ฐ ๋ณ„๋„์˜ ์ธ์Šคํ„ด์Šค๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ณ  ์žˆ๋‹ค.

Keep in mind that all this setup uses single-nodes for all services, including Kafka. For larger loads, youโ€™d need a beefy machine with lots of RAM and disk storage. To scale up even further, you are very likely to use clusters with a more complex tool, such as Kubernetes. Due to self-hosted installationsโ€™ very custom nature, we do not offer any recommendations or guidance around scaling up.

Spring Boot

์‹œ์Šคํ…œ์„ ๊ตฌ์„ฑํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Spring Boot๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด sentry-spring-boot-starter๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ž๋™ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

implementation platform('io.sentry:sentry-bom:6.19.0')
implementation 'io.sentry:sentry-spring-boot-starter'

When you are using multiple Sentry dependencies, you can avoid specifying the version of each dependency with a BOM or Bill Of Materials.

๊ฐœ๋ฐœ์ž๊ฐ€ ์ฒดํฌํ•˜์ง€ ์•Š์€ ์˜ˆ์™ธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ˆ˜์ง‘๋˜๋ฉฐ @ExceptionHandler๋ฅผ ์„ ์–ธํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜์—์„œ Sentry ์„œ๋ฒ„๋กœ ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๋„๋ก ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

import io.sentry.Sentry;

try {
    throw new Exception("This is a test.");
} catch (Exception e) {
    Sentry.captureException(e);
}

์˜ˆ์™ธ ์ˆ˜์ง‘ ์ •๋ณด ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

Advanced Usage ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ Sentry์— ์ˆ˜์ง‘๋œ ์˜ค๋ฅ˜๋ฅผ ๋ณด๋‚ด๊ธฐ ์ง์ „์— ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝœ๋ฐฑ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋‹ค. ๋…ธ์ถœ๋˜๋ฉด ์•ˆ๋˜๋Š” ์ •๋ณด๋Š” ๋ช…์‹œ์ ์œผ๋กœ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ˆ˜์ง‘ํ•˜์ง€ ์•Š์„ ์˜ˆ์™ธ ํด๋ž˜์Šค์— ๋Œ€ํ•ด์„œ๋Š” Ignored Exceptions For Type์„ ์ง€์ •ํ•˜์—ฌ ์ œ์™ธ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

sentry.ignored-exceptions-for-type:
  - org.springframework.security.access.AccessDeniedException
  - org.springframework.security.authentication.BadCredentialsException

ํŠน์ • ์˜ˆ์™ธ ํด๋ž˜์Šค ์ด์™ธ์— ์ผ๋ถ€ ์—๋Ÿฌ ์ด๋ฒคํŠธ๋ฅผ ํ•„ํ„ฐ๋งํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด SentryOptions.BeforeSendCallback ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

@Component
public class CustomBeforeSendCallback implements SentryOptions.BeforeSendCallback {
    @Override
    public SentryEvent execute(SentryEvent event, Hint hint) {
        // Example: Never send server name in events
        event.setServerName(null);
        return event;
    }
}

์‚ฌ์šฉ์ž ์ •๋ณด ์ˆ˜์ง‘ํ•˜๊ธฐ

Spring MVC ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด Record User Information ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ด๋ฆ„(Principal#name)๊ณผ IP ์ฃผ์†Œ๋ฅผ ์ˆ˜์ง‘ํ•˜๋„๋ก ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ, ์Šคํ”„๋ง ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์ฆ ์ฒด๊ณ„๋ฅผ ๊ตฌํ˜„ํ•˜์˜€๋‹ค๋ฉด UserDetails์˜ Username์ด ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ๊ธฐ๋ก๋œ๋‹ค.

sentry.send-default-pii: true

๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์ฒ˜๋ฆฌ

Sentryโ€™s SDK for Java๋Š” ์Šค์ฝ”ํ”„์™€ ์ปจํ…์ŠคํŠธ๋ฅผ ThreadLocal์— ์ €์žฅํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ๋‹ค. Async Methods ๋ฌธ์„œ์— ๋”ฐ๋ฅด๋ฉด Sentry Context์—์„œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ThreadPoolTaskExecutor ๋‚ด์— SentryTaskDecorator๋ฅผ ์ ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์„ค๋ช…ํ•œ๋‹ค.

@Configuration(proxyBeanMethods = false)
public class SentryConfiguration {
    @Bean
    public SentryTaskDecorator sentryTaskDecorator() {
        return new SentryTaskDecorator();
    }
}

@Configuration
public class AsyncMethodConfiguration implements AsyncConfigurer {

    private final SentryTaskDecorator sentryTaskDecorator;

    public AsyncMethodConfiguration(SentryTaskDecorator sentryTaskDecorator) {
        this.sentryTaskDecorator = sentryTaskDecorator;
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setTaskDecorator(sentryTaskDecorator);
        executor.initialize();
        return executor;
    }
}

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜


TransactionPerfomanceCollector์— ์˜ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์œผ๋ฉฐ 6.13.0 ๊ทธ๋ฆฌ๊ณ  6.13.1 ์—์„œ OOM ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ๋‹ค.

  • 6.13.0 - Prevent OOM by disabling TransactionPerformanceCollector for now (#2498)
  • 6.13.1 - Fix transaction performance collector oom (#2505)

์ด์™ธ์—๋„ ์ง€์†์ ์œผ๋กœ ์„ฑ๋Šฅ ๊ฐœ์„ ๊ณผ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๊ณ  ์žˆ์œผ๋‹ˆ ์ฃผ๊ธฐ์ ์œผ๋กœ Sentry ์„œ๋ฒ„๋ฅผ ์—…๊ทธ๋ ˆ์ด๋“œํ•ด์•ผํ•  ํ•„์š”์„ฑ์ด ์žˆ์–ด๋ณด์ธ๋‹ค.

Vue

Sentry for Vue๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ Vue ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜๋“ค๋„ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

npm install --save @sentry/vue
sentry.js
import Vue from 'vue' import * as Sentry from '@sentry/vue' import axios from 'axios'; export function init(router) { Sentry.init({ Vue, dsn: process.env.SENTRY_DSN, envinroment: process.env.NODE_ENV, release: process.env.SENTRY_RELEASE integrations: [ new Sentry.BrowserTracing({ routingInstrumentation: Sentry.vueRouterInstrumentation(router) }), ], tracingOptions: { trackComponents: true }, attachProps: true, logErrors: true, tracesSampleRate: 1.0, }) }

process.env.SENTRY_DSN์™€ process.env.SENTRY_RELEASE๋Š” ๋นŒ๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ์ฃผ์ž…๋˜๋„๋ก ๊ตฌํ˜„ํ•ด์•ผํ•˜๋ฉฐ process.env.SENTRY_RELEASE๋Š” SourceMap์„ ์—…๋กœ๋“œํ•˜๋Š” ๊ณผ์ •์—์„œ ๋“ฑ๋กํ•˜๋Š” ๋ฆด๋ฆฌ์ฆˆ ๋ฒ„์ „๊ณผ ๋™์ผํ•ด์•ผํ•œ๋‹ค.

API ์˜ค๋ฅ˜ ์‹œ ์š”์ฒญ๊ณผ ์‘๋‹ต ์ •๋ณด ์ˆ˜์ง‘ํ•˜๊ธฐ

Browser JavaScript SDK์—์„œ๋„ ๊ธฐ๋ณธ์ ์ธ ์Šคํฌ๋ฆฝํŠธ ์˜ค๋ฅ˜๋Š” ์ž๋™์œผ๋กœ ์ˆ˜์ง‘๋˜๋ฉฐ Axios์™€ ๊ฐ™์€ HTTP ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด API ์š”์ฒญ ๊ณผ์ •์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด Sentry๋กœ ์ˆ˜์ง‘๋˜๋„๋ก ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค.

axios.interceptors.response.use(
    response => response,
    error => {
        const { url, params, data } = error.config
        Sentry.setContext('Request', {
            url,
            params,
            data
        })

        const { status, data } = error.config
        Sentry.setContext('Response', {
            status,
            data
        })

        Sentry.captureException(error)
        return Promise.reject(error)
    })

์ธ์ฆ ์‚ฌ์šฉ์ž ์ •๋ณด ์ˆ˜์ง‘ํ•˜๊ธฐ

Identify Users ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ์•„์ดํ”ผ ์ฃผ์†Œ๋ฅผ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ์•„์ดํ”ผ ์ฃผ์†Œ๊ฐ€ ์ˆ˜์ง‘๋˜๋Š”๋ฐ ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž๋ผ๋ฉด ์‚ฌ์šฉ์ž ์‹๋ณ„ ์•„์ด๋””๋‚˜ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ๋ณด๋‹ค ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

Sentry.setUser({ 
  id: window.auth.userId,
  username: window.auth.userName,
  ip_address: '{{auto}}'
})

If the userโ€™s ip_address is set to โ€œโ€œ, Sentry will infer the IP address from the connection between your app and Sentryโ€™s server.

์Šคํƒ ํŠธ๋ ˆ์ด์Šค ์ถ”์ ํ•˜๊ธฐ

์ผ๋ฐ˜์ ์œผ๋กœ Vue์™€ ๊ฐ™์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋นŒ๋“œ๋˜์–ด ๋ฐฐํฌ๋˜๋Š” ๊ฒฝ์šฐ์— ๋ฒˆ๋“ค์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์น˜๊ฒŒ ๋˜๋ฏ€๋กœ ์˜ค๋ฅ˜๊ฐ€ Sentry์— ์ˆ˜์ง‘๋˜๋”๋ผ๋„ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ํ†ตํ•ด ์›์ธ์ด ๋˜๋Š” ์ฝ”๋“œ ๋ผ์ธ์„ ์ œ๋Œ€๋กœ ์ฐพ์•„๊ฐ€๊ธฐ ํž˜๋“ค ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ Sentry ์—์„œ ๋งŒํผ์€ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก SourceMap์„ ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค. ๋‹ค์Œ์€ Webpack์„ ๋ฒˆ๋“ค๋Ÿฌ๋กœ์จ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์„๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๋Š” ์˜ˆ์‹œ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.

npm install --save-dev @sentry/webpack-plugin
webpack.config.prd.js
const SentryWebpackPlugin = require("@sentry/webpack-plugin") module.exports = { devtool: "source-map", plugins: [ new SentryWebpackPlugin({ org: process.env.SENTRY_ORG, project: process.env.SENTRY_PROJECT, include: "./dist", ignore: ["node_modules", "webpack.config.js", "webpack.config.prod.js"], authToken: process.env.SENTRY_AUTH_TOKEN, release: process.env.SENTRY_RELEASE }) ] }

SENTRY_RELEASE๋Š” ๋นŒ๋“œ์™€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์˜ ๊ฐ’์„ ๋™์ผํ•˜๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ Sentry์—์„œ ์ œ๋Œ€๋กœ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์Œ์— ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค. ๋Ÿฐํƒ€์ž„ ๊ตฌ์„ฑ ์‹œ ์‚ฌ์šฉํ•˜๋Š” DSN๊ฐ€ ์•„๋‹ˆ๋ผ Sentry ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ํ† ํฐ์„ ๋ฐœ๊ธ‰ํ•ด์•ผํ•˜๋ฉฐ ํ”„๋กœ์ ํŠธ ์ •๋ณด๋„ ํฌํ•จํ•ด์•ผํ•œ๋‹ค.

๋๋งˆ์น˜๋ฉฐ

์นด์นด์˜คํŽ˜์ด์—์„œ ๊ณต์œ ํ•œ Sentry๋กœ ์šฐ์•„ํ•˜๊ฒŒ ํ”„๋ก ํŠธ์—”๋“œ ์—๋Ÿฌ ์ถ”์ ํ•˜๊ธฐ์™€ ๋ผ์ธ์—์„œ ๊ณต์œ ํ•œ Sentry๋กœ ์‚ฌ๋‚ด ์—๋Ÿฌ ๋กœ๊ทธ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ ๊ตฌ์ถ•ํ•˜๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ Sentry ํ™œ์šฉ์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ์•Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋„์ž…์€ ์‰ฌ์›Œ๋ณด์ด์ง€๋งŒ ์›ํ•˜๋Š” ๋ฐฉ์‹๋Œ€๋กœ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•˜๊ธฐ์—๋Š” ์ƒ๊ฐ๋ณด๋‹ค ์–ด๋ ค์šด ๊ฒƒ ๊ฐ™๋‹ค. ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ”„๋ก ํŠธ์—”๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” Data Source Name (DSN)๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์— ๋…ธ์ถœ๋˜๋ฏ€๋กœ ๋ณด์•ˆ ๊ด€์ ์—์„œ๋Š” ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—๋งŒ ๋„์ž…ํ•ด์•ผํ•  ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋œ๋‹ค.