vendredi 15 novembre 2019

Trouble organizing code--should I use classes or just functions? Same file or different files?

I'm building a small app that generates metrics to send to a database and I'm having trouble thinking about how to organize it so that it is a) more readable, and b) more concise. The code for each piece of functionality is already written for the most part

The app will ultimately need to take input from the user on which of each of the following items it will use to run:

  • Generate metrics in 3 different formats
  • Generate the chosen format in one of 5 different metric use cases (basically which type of metric, as opposed to format; i.e., appmetrics, server metrics, logs, financial data, etc.). There should be 5 of these options.
  • Write the metrics over HTTP or UDP
  • Write to Kafka (Kafka producer) or directly to the database

In case it matters in the decision making, each option in each bullet point can be selected with any of the others so the total permutations of possible metric-generating options are 3*5*2*2=60. The reason I'm having trouble organizing this is that most of the functions I would write have similar structure but I don't want to be writing small variations 60 times. That seems very messy and a bad practice, no?

I think I'll gather user input with a config file (users of this will understand config files) but I need to figure out a way to inject these values into the program dynamically so I don't have to repeat so much code.

I'm pretty sure this is done all the time but I'm new to this so any help would be appreciated!

If applicable, below is some sample code that exemplifies the problem. Also note that there are function parameters the user will also be able to specify (batch_size, num_batches, interval, etc.) and I'm not attached to these being part of a function, necessarly:

bucket = "default"
org = "org"
token = os.environ['TOKEN']

regions = ['us-west-1','us-west2','us-east-1','us-east-2','ap-southeast-2','eu-west-1']
apps = ['checkout','shoes','payment','frontend',]
user_sessions = range(5,2000,45)
num_xactions = range(0,11)

def influx_metric_gen(batch_size=5, num_batches=100, interval=5, use_case='biz_intel', write_once=False): 

    url = "http://localhost:9999"
    client = InfluxDBClient(url=url, token=token, org=org, debug=True)
    write_api = client.write_api(write_options=SYNCHRONOUS)

    if use_case == 'biz_intel':
        # write biz_intel metrics
        apps = ['checkout','shoes','payment','frontend']
        user_sessions = range(5,2000,45)
        num_xactions = range(0,11)

        if write_once:
            # writes one batch
            points = []
            for x in range(0,batch_size):
                points.append(Point("biz_intel").tag("region", random.choice(regions)) \
                                    .tag("app",random.choice(apps)) \
                                    .field("user_sessions", random.choice(user_sessions)) \
                                    .field("num_transactions",random.choice(num_xactions)) \
                                    .time(time.time_ns()))
            write_api.write(bucket=bucket, org=org, record=points)
        else:
            # generates num_batches of batches   
            for i in range(0,num_batches):
                points = []
                #local = time.localtime()
                for x in range(0,batch_size):
                    points.append(Point("biz_intel").tag("region", random.choice(regions)) \
                                        .tag("app",random.choice(apps)) \
                                        .field("user_sessions", random.choice(user_sessions)) \
                                        .field("num_transactions",random.choice(num_xactions)) \
                                        .time(time.time_ns()))
                write_api.write(bucket=bucket, org=org, record=points)
                sleep(interval)


    elif use_case == 'devops':
        # write devops metrics
        host_prefixes = ['a','b','c','d']
        host_suffixes = range(0,5)
        host = random.choice(host_prefixes) + str(random.choice(host_suffixes))

        # More to add here (not relevant for question)



def graphite_metric_gen(batch_size=5, num_batches=100, interval=5, use_case='biz_intel', write_once=False): 

    if use_case == 'biz_intel':

        apps = ['checkout','shoes','payment','frontend']
        user_sessions = range(5,2000,45)
        num_xactions = range(0,11)       

        if write_once:
            for x in range(0,batch_size):
                points.append(f"biz_intel.{random.choice(regions)}.{random.choice(apps)}.user_sessions {random.choice(user_sessions)} {time.time_ns()}")
                points.append(f"biz_intel.{random.choice(regions)}.{random.choice(apps)}.num_transactions {random.choice(num_xactions)} {time.time_ns()}")
            write_api.write(bucket=bucket, org=org, record=points)
        else:       
            for i in range(0,num_batches):
                points = []
                #local = time.localtime()
                for x in range(0,batch_size):
                    points.append(f"biz_intel.{random.choice(regions)}.{random.choice(apps)}.user_sessions {random.choice(user_sessions)} {time.time_ns()}")
                    points.append(f"biz_intel.{random.choice(regions)}.{random.choice(apps)}.num_transactions {random.choice(num_xactions)} {time.time_ns()}")
                write_api.write(bucket=bucket, org=org, record=points)
                sleep(interval)

            # More to add here (not relevant for question)
    ```

Aucun commentaire:

Enregistrer un commentaire