Ini adalah versi kode saya yang sangat disingkat (saya akan menaruh tautan ke semuanya di komentar)

import ...

...

def main(data, context):
    log_client = logging.Client()

    log_name = 'cloudfunctions.googleapis.com%2Fcloud-functions'

    res = Resource(type="cloud_function",
                   labels={
                       "function_name": "refresh_classes",
                       "region": os.environ.get("FUNC_REGION")
                   })
    logger = log_client.logger(log_name.format(os.environ.get("PROJECT_ID")))

    db = sqlalchemy.create_engine(
        sqlalchemy.engine.url.URL(
            drivername="mysql+pymysql",
            username=os.environ.get("DB_USER"),
            password=os.environ.get("DB_PASS"),
            host=os.environ.get("DB_HOST"),
            port=3306,
            database=PRIMARY_TABLE_NAME
        ),
        pool_size=5,
        max_overflow=2,
        pool_timeout=30,
        pool_recycle=1800
    )
    start_time = perf_counter()

    check_if_table_exists(db)

    for i in range(START_IDX, END_IDX):
        print(i)
        logger.log_text(f"Checking class with id {i}", resource=res, severity="INFO")

        ...

    logger.log_text(f"Total seconds elapsed: {perf_counter() - start_time}", resource=res, severity="INFO")


if __name__ == '__main__':
    main('data', 'context')

Ketika saya menjalankan fungsi cloud di atas secara lokal, dengan GOOGLE_APPLICATION_CREDENTIALS saya dikonfigurasi bersama dengan pengaturan proxy Cloud MySQL lokal saya, pencatatan cloud verbose muncul dan fungsi selesai tanpa hambatan, persis seperti yang saya harapkan:

enter image description here

Namun, ketika saya menerapkan semuanya ke GCP, dan mencoba memicunya melalui konsol (pemicu perpesanan cloud), yang saya dapatkan hanyalah ini dalam hal logging:

enter image description here

teks sebenarnya

{
 insertId: "******"  
 labels: {
  execution_id: "******"   
 }
 logName: "projects/******/logs/cloudfunctions.googleapis.com%2Fcloud-functions"  
 receiveTimestamp: "2020-05-29T22:11:13.435688367Z"  
 resource: {
  labels: {
   function_name: "******"    
   project_id: "******"    
   region: "us-central1"    
  }
  type: "cloud_function"   
 }
 severity: "DEBUG"  
 textPayload: "Function execution started"  
 timestamp: "2020-05-29T22:11:03.069889708Z"  
 trace: "projects/******/traces/******"  
}

{
 insertId: "******"  
 labels: {
  execution_id: "******"   
 }
 logName: "projects/******/logs/cloudfunctions.googleapis.com%2Fcloud-functions"  
 receiveTimestamp: "2020-05-29T22:11:16.331311285Z"  
 resource: {
  labels: {
   function_name: "******"    
   project_id: "******"    
   region: "us-central1"    
  }
  type: "cloud_function"   
 }
 severity: "DEBUG"  
 textPayload: "Function execution took 12362 ms, finished with status: 'crash'"  
 timestamp: "2020-05-29T22:11:15.430033249Z"  
 trace: "projects/******/traces/******"  
}

*Saya tidak begitu tahu apa itu informasi sensitif dan apa yang tidak, jadi saya hanya membintangi beberapa hal acak

Saat saya menulis ini, saya menyadari lebih banyak logging dapat membantu, jadi saya memasukkan logger Google di antara pengaturan logger, pengaturan db, dan pemeriksaan tabel yang saya jalankan.

Fungsi tersebut mogok bahkan sebelum Google logger disiapkan.

Jadi pada titik ini saya tidak begitu yakin apa yang dapat merusak fungsi saya, dan saya tidak tahu bagaimana cara mengetahuinya, mengingat pencatatan Google Cloud tidak membantu. Kesalahan json memiliki properti trace yang terlihat sangat menjanjikan, karena yang saya butuhkan saat ini hanyalah jejak tumpukan Python, tetapi saya tidak tahu apakah ada cara untuk melihatnya.

Saya harus memperhatikan bahwa saya memiliki variabel lingkungan yang dikonfigurasi melalui konsol Cloud Function GCP.

enter image description here

Pada prinsipnya, ada dua hal yang akan membantu:

  1. cara melihat jejak tumpukan python dari fungsi cloud yang mogok
  2. apa, khusus untuk aplikasi saya, yang dapat menyebabkannya menunjukkan perilaku mogok ini
0
notacorn 30 Mei 2020, 01:24

1 menjawab

Jawaban Terbaik

Jadi saya akhirnya menemukan bahwa jika, alih-alih memicu fungsi cloud Anda melalui Cloud Scheduler, Anda menjalankan fungsi secara manual melalui Test Function

enter image description here

GCP akan memberi Anda pengecualian yang diajukan. Dalam kasus saya, koneksi Cloud MySQL saya gagal

Error: function terminated. Recommended action: inspect logs for termination reason. Details:
(pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '**.***.**.***' (timed out)")
(Background on this error at: http://sqlalche.me/e/e3q8)

Jadi saya hanya perlu memperkenalkan variabel lingkungan untuk beralih antara menghubungkan melalui proxy dan soket unix seperti:

if os.environ.get("ENV") == "local":
    db = sqlalchemy.create_engine(
        sqlalchemy.engine.url.URL(
            drivername="mysql+pymysql",
            username=os.environ.get("DB_USER"),
            password=os.environ.get("DB_PASS"),
            host=os.environ.get("DB_HOST"),
            port=3306,
            database=PRIMARY_TABLE_NAME
        ),
        pool_size=5,
        max_overflow=2,
        pool_timeout=30,
        pool_recycle=1800
    )
else:
    db = sqlalchemy.create_engine(
        sqlalchemy.engine.url.URL(
            drivername="mysql+pymysql",
            username=os.environ.get("DB_USER"),
            password=os.environ.get("DB_PASS"),
            database=PRIMARY_TABLE_NAME,
            query={"unix_socket": "/cloudsql/{}".format(os.environ.get("CLOUD_SQL_CONNECTION_NAME"))}
        ),
        pool_size=5,
        max_overflow=2,
        pool_timeout=30,
        pool_recycle=1800
    )
2
notacorn 30 Mei 2020, 17:55