서버리스 TypeScript API: Azure Functions를 사용하여 MongoDB에 데이터 저장

Mongoose API를 사용하여 데이터를 Azure Cosmos DB에 저장하는 Azure Function API를 만든 다음, 공용 HTTP 엔드포인트를 사용하여 호스팅하기 위해 Azure 클라우드에 함수 애플리케이션을 배포합니다.

참고 항목

이 문서에서는 현재 미리 보기로 제공된 Azure Functions Node.js v4 프로그래밍 모델을 사용합니다.

Flow chart showing path of HTTP request to pass data through Azure Functions and store in Azure Cosmos DB.

개발 환경 준비

다음 소프트웨어를 설치합니다.

1. Visual Studio Code에서 Azure에 로그인

Azure 서비스 확장을 이미 사용하는 경우 이미 로그인되어 있어야 하며 이 단계를 건너뛸 수 있습니다.

Visual Studio Code에 Azure 서비스 확장을 설치한 후에는 Azure 계정에 로그인해야 합니다.

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  2. 리소스 섹션에서 Azure에 로그인을 선택하고 프롬프트를 따릅니다.

    Sign in to Azure through VS Code

  3. 로그인한 후 Azure 계정의 이메일 주소가 상태 표시줄에 나타나고 구독이 Azure 탐색기에 표시되는지 확인합니다.

    VS Code Azure explorer showing subscriptions

2. Azure 리소스 그룹 만들기

리소스 그룹은 지역 기반 리소스 컬렉션입니다. 리소스 그룹을 만든 다음, 해당 그룹에 리소스를 만들어 자습서의 끝에서 각 리소스를 개별적으로 삭제하지 않고도 리소스 그룹을 삭제할 수 있습니다.

  1. Azure Functions 프로젝트의 루트로 사용할 새 폴더를 로컬 시스템에 만듭니다.

  2. Visual Studio Code에서 이 폴더를 엽니다.

  3. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  4. 리소스 아래에서 구독을 찾고 아이콘을 + 선택한 다음, 리소스 그룹 만들기를 선택합니다.

  5. 다음 표를 사용하여 프롬프트를 완료합니다.

    prompt
    새 리소스 그룹의 이름 입력 azure-tutorial
    새 리소스의 위치를 선택합니다. 가까운 지리적 지역을 선택합니다.

3. 로컬 Functions 앱 만들기

HTTP 트리거 함수를 포함하는 로컬 Azure Functions(서버리스) 애플리케이션을 만듭니다.

  1. Visual Studio Code에서 명령 팔레트(Ctrl + Shift + P)를 엽니다.

  2. Azure Functions: 새 프로젝트 만들기를 검색하여 선택합니다.

  3. 다음 표를 사용하여 로컬 Azure Function 프로젝트 만들기를 완료합니다.

    prompt 주의
    함수 프로젝트를 포함할 폴더 선택 현재(기본값) 폴더를 선택합니다.
    언어 선택 TypeScript
    TypeScript 프로그래밍 모델 선택 모델 V4(미리 보기)
    프로젝트의 첫 번째 함수에 대한 템플릿 선택 HTTP 트리거 HTTP 요청을 사용하여 API가 호출됩니다.
    함수 이름 제공 blogposts API 경로는 /api/blogposts
  4. Visual Studio Code에서 프로젝트를 만들 때 파일에서 ./src/functions/blogposts.ts API 코드를 봅니다.

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    
    export async function blogposts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function processed request for url "${request.url}"`);
    
        const name = request.query.get('name') || await request.text() || 'world';
    
        return { body: `Hello, ${name}!` };
    };
    
    app.http('blogposts', {
        methods: ['GET', 'POST'],
        authLevel: 'anonymous',
        handler: blogposts
    });
    

    이 코드는 새 v4 프로그래밍 모델의 표준 상용구입니다. POST 및 GET을 사용하여 API 계층을 작성하는 유일한 방법을 나타내기 위한 것은 아닙니다.

  5. GET 요청만 모든 블로그 게시물을 반환할 수 있도록 이전 코드를 다음 코드로 바꿉니다.

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    
    // curl --location 'http://localhost:7071/api/blogposts' --verbose
    export async function getBlogPosts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function getBlogPosts processed request for url "${request.url}"`);
    
        // Empty array for now ... will fix later
        const blogposts = [];
    
        return {
            status: 200,
            jsonBody: {
                blogposts
            }
        };
    };
    
    app.get('getBlogPosts', {
        route: "blogposts",
        authLevel: 'anonymous',
        handler: getBlogPosts
    });
    

    이 코드에는 다음과 같은 몇 가지 Azure Functions Node.js v4 프로그래밍 모델 변경 내용 이 있습니다.

    • GET 요청임을 나타내는 함수 이름은 getBlobPosts로그에서 함수를 격리하는 데 도움이 됩니다.
    • 속성은 route 제공된 기본 API 경로의 일부인 로 설정 blogposts됩니다 /api/blogposts.
    • methods 개체의 사용 get 이 GET 요청임을 나타내므로 app 속성이 제거되었으며 불필요합니다. 메서드 함수는 아래에 나열되어 있습니다. 다른 메서드가 있는 경우 속성 사용 methods 으로 돌아갈 수 있습니다.
      • deleteRequest()
      • get()
      • patch()
      • post()
      • put()

4. Azurite 로컬 스토리지 에뮬레이터 시작

로컬 컴퓨터에서 함수를 개발하려면 Storage 에뮬레이터(무료) 또는 Azure Storage 계정(유료)이 필요합니다.

별도의 터미널에서 Azurite 로컬 스토리지 에뮬레이터를 시작합니다.

azurite --silent --location ./azurite --debug ./azurite/debug.log

로컬 Azure Storage 에뮬레이터를 사용하여 Azure Functions를 로컬로 실행하는 데 필요합니다. 로컬 스토리지 에뮬레이터는 값UseDevelopmentStorage=true이 있는 AzureWebJobsStorage 속성을 사용하여 파일에 지정됩니다local.settings.json.

{
    "IsEncrypted": false,
    "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing"
    }
}

azurite 하위 폴더가 파일에 이미 추가 .gitignore 되었습니다.

5. 로컬 서버리스 함수 실행

Azure Functions 프로젝트를 Azure에 배포하기 전에 로컬로 실행하여 테스트합니다.

  1. Visual Studio Code에서 getBlogPosts 함수의 끝에 있는 문에 return 중단점을 설정합니다.

  2. Visual Studio Code에서 F5 키를 눌러 디버거를 시작하고 Azure Functions 호스트에 연결합니다.

    디버그>시작 디버깅 메뉴 명령을 사용할 수도 있습니다.

  3. 출력이 터미널 패널에 나타납니다.

  4. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  5. 작업 영역 섹션에서 로컬 프로젝트 -Functions ->>getBlogPosts를 찾아 확장합니다.

  6. 함수 이름을 마우스 오른쪽 단추로 클릭하고 getBlogPosts 클릭한 다음 함수 URL 복사를 선택합니다.

    Partial screenshot of Visual Studio Code, with the Azure Function's button named Copy Function URL highlighted.

  7. 브라우저에서 URL을 붙여넣고 Enter 키를 선택하거나 터미널에서 다음 cURL 명령을 사용합니다.

    curl http://localhost:7071/api/blogposts --verbose
    

    빈 블로그 게시물 배열의 응답은 다음과 같이 반환됩니다.

    *   Trying 127.0.0.1:7071...
    * Connected to localhost (127.0.0.1) port 7071 (#0)
    > GET /api/blogposts HTTP/1.1
    > Host: localhost:7071
    > User-Agent: curl/7.88.1
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    < Date: Mon, 08 May 2023 17:35:24 GMT
    < Server: Kestrel
    < Transfer-Encoding: chunked
    <
    {"blogposts":[]}* Connection #0 to host localhost left intact
    
  8. VS Code에서 디버거, Shift + F5를 중지합니다.

6. Visual Studio Code에서 Azure Function 앱 만들기

이 섹션에서는 Azure 구독에서 함수 앱 클라우드 리소스 및 관련 리소스를 만듭니다.

  1. Visual Studio Code에서 명령 팔레트(Ctrl + Shift + P)를 엽니다.

  2. Azure Functions: Azure에서 함수 앱 만들기(고급)를 검색하여 선택합니다.

  3. 프롬프트에서 다음 정보를 제공합니다.

    프롬프트 선택 사항
    함수 앱에 대해 전역적으로 고유한 이름 입력 URL 경로에 유효한 이름(예: first-function.)을 입력합니다. URL을 전역적으로 고유하게 만들기 위해 3자를 추가했습니다. 입력한 이름이 Azure Functions에서 고유한지 확인하기 위해 유효성을 검사합니다.
    런타임 스택 선택 Node.js 18 LTS 또는 최신 버전을 선택합니다.
    OS 선택 Linux를 선택합니다.
    새 리소스에 대한 리소스 그룹 선택 azure-tutorial-first-function이라는 새 리소스 그룹을 만듭니다. 이 리소스 그룹에는 결국 Azure Function, Azure Storage 및 Cosmos DB for MongoDB API와 같은 여러 리소스가 있습니다.
    호스팅 계획 선택 소비를 선택합니다.
    스토리지 계정 선택 새 스토리지 계정 만들기를 선택하고 기본 이름을 적용합니다.
    에 대한 Application Insights 리소스를 선택합니다. 새 Application Insights 리소스 만들기를 선택하고 기본 이름을 적용합니다.

    알림이 앱이 만들어졌는지 확인할 때까지 기다립니다.

7. Visual Studio Code에서 Azure에 Azure Function 앱 배포

Important

기존 함수 앱에 배포하면 항상 Azure에서 해당 앱의 콘텐츠를 덮어씁니다.

  1. 작업 표시줄에서 Azure 아이콘을 선택한 다음, 리소스 영역에서 함수 앱 리소스를 마우스 오른쪽 단추로 클릭하고 함수 앱에 배포를 선택합니다.
  2. 배포할 것인지 묻는 메시지가 표시되면 배포를 선택합니다.
  3. 배포가 완료되면 몇 가지 옵션이 포함된 알림이 표시됩니다. 출력 보기를 선택하여 결과를 봅니다. 알림이 누락된 경우 오른쪽 아래 모서리에 있는 벨 아이콘을 선택하여 다시 확인합니다.

8. 클라우드 앱에 애플리케이션 설정 추가

  1. 작업 표시줄에서 Azure 아이콘을 선택한 다음 리소스 영역에서 함수 앱 리소스를 확장하고 애플리케이션 설정 선택합니다.

  2. 새 설정 추가를 선택하고 다음 설정을 추가하여 Node.js v4(미리 보기) 프로그래밍 모델을 사용하도록 설정합니다.

    설정
    AzureWebJobsFeatureFlags EnableWorkerIndexing

9. 원격 서버리스 함수 실행

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  2. 리소스 섹션에서 Azure Function 앱 리소스를 확장합니다. 함수 이름을 마우스 오른쪽 단추로 클릭하고 함수 URL 복사를 선택합니다.

  3. URL을 브라우저에 붙여넣습니다. 함수를 로컬로 실행할 때와 동일한 빈 배열이 반환됩니다.

    {"blogposts":[]}
    

10. Azure Cosmos DB for MongoDB API 통합 추가

Azure Cosmos DB는 친숙한 통합 지점을 제공하는 MongoDB API를 제공합니다.

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  2. 리소스 섹션에서 선택한 다음 데이터베이스 서버 만들기를 선택합니다 +. 다음 표를 사용하여 새 Azure Cosmos DB 리소스를 만드는 프롬프트를 완료합니다.

    prompt 주의
    Azure 데이터베이스 서버 선택 Azure Cosmos DB for MongoDB API
    Azure Cosmos DB 계정 이름을 제공합니다. cosmosdb-mongodb-database 고유한 이름을 만들기 위해 세 문자를 추가했습니다. 이름은 API URL의 일부가 됩니다.
    용량 모델 선택 서버를 사용하지 않음
    새 리소스에 대한 리소스 그룹 선택 azure-tutorial-first-function 이전 섹션에서 만든 리소스 그룹을 선택합니다.
    새 리소스의 위치 선택 권장 지역을 선택합니다.

11. mongoose 종속성 설치

Visual Studio Code 터미널에서 Ctrl + Shift를 누른 + ` 다음 npm 패키지를 설치합니다.

npm install mongoose

12. 블로그 게시물에 대한 mongoose 코드 추가

  1. Visual Studio Code에서 lib./src/라는 하위 디렉터리를 만들고, 명명된 ./database.ts 파일을 만들고, 다음 코드를 복사합니다.

    import { Schema, Document, createConnection, ConnectOptions, model, set } from 'mongoose';
    
    const connectionString = process.env.MONGODB_URI;
    console.log('connectionString', connectionString);
    
    const connection = createConnection(connectionString, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      autoIndex: true
    } as ConnectOptions);
    
    export interface IBlogPost {
      author: string
      title: string
      body: string
    }
    
    export interface IBlogPostDocument extends IBlogPost, Document {
      id: string
      created: Date
    }
    
    const BlogPostSchema = new Schema({
      id: Schema.Types.ObjectId,
      author: String,
      title: String,
      body: String,
      created: {
        type: Date,
        default: Date.now
      }
    });
    
    BlogPostSchema.set('toJSON', {
      transform: function (doc, ret, options) {
          ret.id = ret._id;
          delete ret._id;
          delete ret.__v;
      }
    }); 
    
    export const BlogPost = model<IBlogPostDocument>('BlogPost', BlogPostSchema);
    
    connection.model('BlogPost', BlogPostSchema);
    
    export default connection;
    
  2. Visual Studio Code에서 파일을 열고 ./src/functions/blogposts 전체 파일의 코드를 다음으로 바꿉다.

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    import connection from '../lib/database';
    
    // curl --location 'http://localhost:7071/api/blogposts' --verbose
    export async function getBlogPosts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function getBlogPosts processed request for url "${request.url}"`);
    
        const blogposts = await connection.model('BlogPost').find({});
    
        return {
            status: 200,
            jsonBody: {
                blogposts
            }
        };
    };
    
    app.get('getBlogPosts', {
        route: "blogposts",
        authLevel: 'anonymous',
        handler: getBlogPosts
    });
    

13. 로컬 앱에 연결 문자열 추가

  1. Visual Studio Code의 Azure 탐색기에서 Azure Cosmos DB 섹션을 선택하고 확장하여 새 리소스를 마우스 오른쪽 단추로 클릭합니다.

  2. 연결 문자열 복사를 선택합니다.

  3. Visual Studio Code에서 파일 탐색기를 사용하여 엽니다 ./local.settings.json.

  4. 호출 MONGODB_URI 된 새 속성을 추가하고 연결 문자열 값을 붙여넣습니다.

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "node",
        "AzureWebJobsFeatureFlags": "EnableWorkerIndexing",
        "MONGODB_URI": "mongodb://...."
      }
    }
    

    파일의 ./local.settings.json 비밀:

    • 파일에 포함되어 있으므로 Azure에 ./.funcignore 배포되지 않습니다.
    • 파일에 포함되어 ./.gitignore 있으므로 소스 제어에 검사 않습니다.
  5. 애플리케이션을 로컬로 실행하고 이전 섹션에서 동일한 URL로 API를 테스트합니다.

14. 원격 앱에 연결 문자열 추가

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.
  2. 리소스 섹션에서 Azure Cosmos DB 인스턴스를 찾습니다. 리소스를 마우스 오른쪽 단추로 클릭하고 커넥트 복사 문자열을 선택합니다.
  3. 동일한 리소스 섹션에서 함수 앱을 찾아 노드를 확장합니다.
  4. 애플리케이션 설정 마우스 오른쪽 단추로 클릭하고 새 설정 추가를 선택합니다.
  5. 앱 설정 이름을 MONGODB_URI 입력하고 Enter 키를 선택합니다.
  6. 복사한 값을 붙여넣고 Enter 키를 누릅니다.

15. 블로그 게시물 만들기, 업데이트 및 삭제를 위한 API 추가

  1. Visual Studio Code에서 명령 팔레트를 사용하여 Azure Functions: Create 함수를 찾아 선택합니다.

  2. HTTP 트리거를 선택하고 이름을 지정 blogpost 합니다(단수).

  3. 다음 코드를 파일에 복사합니다.

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    import connection, { IBlogPost, IBlogPostDocument }  from '../lib/database';
    
    // curl -X POST --location 'http://localhost:7071/api/blogpost' --header 'Content-Type: application/json' --data '{"author":"john","title":"my first post", "body":"learn serverless node.js"}' --verbose
    export async function addBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function addBlogPost processed request for url "${request.url}"`);
    
        const body = await request.json() as IBlogPost;
    
        const blogPostResult = await connection.model('BlogPost').create({
            author: body?.author,
            title: body?.title,
            body: body?.body
        });
    
        return {
            status: 200,
            jsonBody: {
                blogPostResult
            }
        };
    };
    
    // curl -X PUT --location 'http://localhost:7071/api/blogpost/64568e727f7d11e09eab473c' --header 'Content-Type: application/json' --data '{"author":"john jones","title":"my first serverless post", "body":"Learn serverless Node.js with Azure Functions"}' --verbose
    export async function updateBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function updateBlogPost processed request for url "${request.url}"`);
    
        const body = await request.json() as IBlogPost;
        const id = request.params.id;
    
        const blogPostResult = await connection.model('BlogPost').updateOne({ _id: id }, {
            author: body?.author,
            title: body?.title,
            body: body?.body
        });
    
        if(blogPostResult.matchedCount === 0) {
            return {
                status: 404,
                jsonBody: {
                    message: 'Blog post not found'
                }
            };
        }
    
        return {
            status: 200,
            jsonBody: {
                blogPostResult
            }
        };
    };
    
    // curl --location 'http://localhost:7071/api/blogpost/6456597918547e37d515bda3' --verbose
    export async function getBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function getBlogPosts processed request for url "${request.url}"`);
    
        console.log('request.params.id', request.params.id)
        const id = request.params.id;
    
        const blogPost = await connection.model('BlogPost').findOne({ _id: id });
    
        if(!blogPost) {
            return {
                status: 404,
                jsonBody: {
                    message: 'Blog post not found'
                }
            };
        }
    
        return {
            status: 200,
            jsonBody: {
                blogPost
            }
        };
    };
    
    // curl --location 'http://localhost:7071/api/blogpost/6456597918547e37d515bda3' --request DELETE --header 'Content-Type: application/json' --verbose
    export async function deleteBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function deleteBlogPost processed request for url "${request.url}"`);
    
        const id = request.params.id;
    
        const blogPostResult = await connection.model('BlogPost').deleteOne({ _id: id });
    
        if(blogPostResult.deletedCount === 0) {
            return {
                status: 404,
                jsonBody: {
                    message: 'Blog post not found'
                }
            };
        }
    
        return {
            status: 200,
            jsonBody: {
                blogPostResult
            }
        };
    };
    
    app.get('getBlogPost', {
        route: "blogpost/{id}",
        authLevel: 'anonymous',
        handler: getBlogPost
    });
    
    app.post('postBlogPost', {
        route: "blogpost",
        authLevel: 'anonymous',
        handler: addBlogPost
    });
    
    app.put('putBlogPost', {
        route: "blogpost/{id}",
        authLevel: 'anonymous',
        handler: updateBlogPost
    });
    
    app.deleteRequest('deleteBlogPost', {
        route: "blogpost/{id}",
        authLevel: 'anonymous',
        handler: deleteBlogPost
    });
    
  4. 디버거를 사용하여 로컬 함수를 다시 시작합니다. 다음 API를 사용할 수 있습니다.

    deleteBlogPost: [DELETE] http://localhost:7071/api/blogpost/{id}
    getBlogPost: [GET] http://localhost:7071/api/blogpost/{id}
    getBlogPosts: [GET] http://localhost:7071/api/blogposts
    postBlogPost: [POST] http://localhost:7071/api/blogpost
    putBlogPost: [PUT] http://localhost:7071/api/blogpost/{id}
    
  5. cURL 명령의 blogpost (단수) API를 사용하여 몇 가지 블로그 게시물을 추가합니다.

    curl -X POST --location 'http://localhost:7071/api/blogpost' --header 'Content-Type: application/json' --data '{"author":"john","title":"my first post", "body":"learn serverless node.js"}' --verbose
    
  6. cURL 명령의 blogposts (복수) API를 사용하여 블로그 게시물을 가져옵니다.

    curl http://localhost:7071/api/blogposts --verbose
    

16. Azure Cosmos DB용 Visual Studio Code 확장을 사용하여 모든 데이터 보기

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.

  2. 리소스 섹션에서 Azure Cosmos DB 데이터베이스를 마우스 오른쪽 단추로 클릭하고 새로 고침을 선택합니다.

  3. 테스트 데이터베이스 및 blogposts 컬렉션 노드를 확장하여 문서를 봅니다.

  4. Azure Cosmos DB 인스턴스에서 데이터를 보려면 나열된 항목 중 하나를 선택합니다.

    Partial screenshot of Visual Studio Code, showing the Azure explorer with the Databases with a selected item displayed in the reading pane.

17. 데이터베이스 코드를 포함하도록 함수 앱 다시 배포

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.
  2. 리소스 섹션에서 Azure Function 앱을 마우스 오른쪽 단추로 클릭하고 함수 앱에 배포를 선택합니다.
  3. 배포할 것인지 묻는 팝업에서 배포를 선택합니다.
  4. 계속하기 전에 배포가 완료될 때까지 기다립니다.

18. 클라우드 기반 Azure Function 사용

  1. Azure 탐색기의 Functions 영역에서 함수를 선택하고 확장한 다음 , API를 나열하는 Functions 노드를 선택합니다.
  2. API 중 하나를 마우스 오른쪽 단추로 클릭하고 함수 URL 복사를 선택합니다.
  3. 로컬 URL 대신 원격 URL 사용하도록 이전 cURL 명령을 편집합니다. 명령을 실행하여 원격 API를 테스트합니다.

19. Azure Function 로그 쿼리

로그를 검색하려면 Azure Portal을 사용합니다.

  1. Visual Studio Code에서 Azure 탐색기를 선택한 다음, Functions에서 함수 앱을 마우스 오른쪽 단추로 클릭한 다음 포털에서 열기를 선택합니다.

    그러면 Azure Function에 대한 Azure Portal이 열립니다.

  2. 설정 Application Insights를 선택한 다음 Application Insights 데이터 보기를 선택합니다.

    Browser screenshot showing menu choices. Select **Application Insights** from the Settings, then select **View Application Insights data**.

    이 링크는 Visual Studio Code를 사용하여 Azure Function을 만들 때 만든 별도의 메트릭 리소스로 이동합니다.

  3. 모니터링 섹션에서 로그를 선택합니다. 쿼리 팝업 창이 표시되면 팝업의 오른쪽 위 모퉁이에 있는 X를 선택하여 닫습니다.

  4. 새 쿼리 1 창의 테이블 탭에서 추적 테이블을 두 번 클릭합니다.

    그러면 Kusto 쿼리, traces가 쿼리 창에 입력됩니다.

  5. 사용자 지정 로그를 검색하도록 쿼리를 편집합니다.

    traces 
    | where message startswith "***"
    
  6. 실행을 선택합니다.

    로그에 결과가 표시되지 않는 경우 Azure Function에 대한 HTTP 요청과 Kusto의 로그 가용성 사이에 몇 분 정도 지연이 있기 때문일 수 있습니다. 몇 분 정도 기다린 후 쿼리를 다시 실행합니다.

    이 로깅 정보를 가져오기 위해 추가 작업을 수행할 필요가 없었습니다.

    • 이 코드는 Function 프레임워크에서 제공하는 함수를 사용 context.log 했습니다. 대신 로깅을 console사용하여 context특정 개별 함수로 필터링할 수 있습니다. 함수 앱에 많은 함수가 있는 경우 유용합니다.
    • 함수 앱이 사용자를 위해 Application Insights를 추가했습니다.
    • Kusto 쿼리 도구는 Azure Portal에 포함되어 있습니다.
    • 로그에서 최소 정보를 얻기 위해 Kusto 쿼리작성하는 방법을 학습하는 대신 선택할 traces 수 있습니다.

20. 리소스 정리

단일 리소스 그룹을 사용했기 때문에 리소스 그룹을 삭제하여 모든 리소스를 삭제할 수 있습니다.

  1. Visual Studio Code에서 기본 사이드바에서 Azure 아이콘을 선택하여 Azure 탐색기를 열거나 바로 가기 키(Shift + Alt + A)를 사용합니다.
  2. Azure를 검색하여 선택합니다 . 리소스 그룹별로 그룹화합니다.
  3. 리소스 그룹을 마우스 오른쪽 단추로 클릭하고 리소스 그룹 삭제를 선택합니다.
  4. 리소스 그룹 이름을 입력하여 삭제를 확인합니다.

사용 가능한 소스 코드

이 Azure Function 앱의 전체 소스 코드:

다음 단계